├── .nvmrc ├── website ├── docs │ ├── bitcoin │ │ ├── FAQ.md │ │ ├── tx │ │ │ ├── rbf.md │ │ │ ├── decode.md │ │ │ ├── _category_.json │ │ │ └── bitgo.md │ │ ├── utils │ │ │ ├── crypto.md │ │ │ └── _category_.json │ │ ├── address │ │ │ └── _category_.json │ │ ├── script │ │ │ └── _category_.json │ │ ├── _category_.json │ │ └── intro.md │ ├── ethereum │ │ ├── FAQ.md │ │ ├── blockchain │ │ │ └── README.md │ │ ├── multisig │ │ │ ├── batch │ │ │ │ └── README.md │ │ │ ├── safe │ │ │ │ ├── helper.md │ │ │ │ ├── deploy.md │ │ │ │ └── _category_.json │ │ │ └── _category_.json │ │ ├── tx │ │ │ ├── erc20.md │ │ │ ├── abi-decode.md │ │ │ ├── abi-decode-erc721.md │ │ │ └── _category_.json │ │ ├── account │ │ │ └── _category_.json │ │ ├── _category_.json │ │ ├── intro.md │ │ └── README.md │ ├── cardano │ │ ├── _category_.json │ │ ├── tx │ │ │ └── _category_.json │ │ └── account │ │ │ └── _category_.json │ ├── cosmos │ │ ├── _category_.json │ │ ├── tx │ │ │ └── _category_.json │ │ ├── delegate │ │ │ └── _category_.json │ │ ├── multisig │ │ │ └── _category_.json │ │ ├── account │ │ │ └── _category_.json │ │ └── intro.md │ ├── aptos │ │ ├── tx │ │ │ ├── _category_.json │ │ │ ├── transaction.md │ │ │ └── submit.md │ │ ├── nft │ │ │ ├── _category_.json │ │ │ ├── nft.md │ │ │ └── transfer.md │ │ ├── account │ │ │ └── _category_.json │ │ ├── multisig │ │ │ ├── _category_.json │ │ │ └── account.md │ │ ├── token │ │ │ ├── _category_.json │ │ │ └── balance.md │ │ ├── _category_.json │ │ └── intro.md │ ├── crosschain │ │ ├── _category_.json │ │ ├── anyswap │ │ │ ├── _category_.json │ │ │ ├── intro.md │ │ │ └── FAQ.md │ │ ├── intro.md │ │ └── README.md │ ├── ton │ │ ├── tx │ │ │ └── _category_.json │ │ ├── account │ │ │ └── _category_.json │ │ ├── _category_.json │ │ ├── token │ │ │ └── _category_.json │ │ └── README.md │ ├── stellar │ │ ├── _category_.json │ │ ├── account │ │ │ └── _category_.json │ │ └── tx │ │ │ └── _category_.json │ ├── tron │ │ ├── _category_.json │ │ ├── account │ │ │ └── _category_.json │ │ ├── tx │ │ │ └── _category_.json │ │ └── intro.md │ ├── ripple │ │ ├── multisig │ │ │ └── _category_.json │ │ ├── tx │ │ │ └── _category_.json │ │ ├── _category_.json │ │ ├── account │ │ │ └── _category_.json │ │ ├── intro.md │ │ └── FAQ.md │ ├── solana │ │ ├── account │ │ │ └── _category_.json │ │ ├── token │ │ │ └── _category_.json │ │ ├── _category_.json │ │ ├── defi │ │ │ └── _category_.json │ │ ├── multisig │ │ │ └── _category_.json │ │ ├── subscribes │ │ │ └── _category_.json │ │ └── intro.md │ ├── polkadot │ │ ├── batch │ │ │ └── _category_.json │ │ ├── tx │ │ │ └── _category_.json │ │ ├── _category_.json │ │ ├── staking │ │ │ └── _category_.json │ │ ├── account │ │ │ └── _category_.json │ │ └── multisig │ │ │ └── _category_.json │ └── avalanche │ │ ├── tx │ │ └── _category_.json │ │ ├── account │ │ └── _category_.json │ │ ├── _category_.json │ │ └── intro.md ├── examples ├── static │ ├── .nojekyll │ ├── robots.txt │ ├── img │ │ ├── banner.jpg │ │ ├── favicon.ico │ │ ├── favicon-16x16.png │ │ └── favicon-32x32.png │ └── icons │ │ ├── avax.svg │ │ ├── eth.svg │ │ ├── gswap.svg │ │ ├── dot.svg │ │ ├── sol.svg │ │ ├── xrp.svg │ │ └── apt.svg ├── robots.txt ├── postcss.config.js ├── src │ ├── lib │ │ └── utils.ts │ └── components │ │ └── ui │ │ ├── avatar.tsx │ │ ├── card.tsx │ │ ├── button.tsx │ │ └── pagination.tsx ├── blog │ ├── authors.yml │ ├── 2024-01-20-ethereum-account.md │ ├── 2024-01-15-bitcoin-script-system.md │ ├── 2024-01-18-bitcoin-transaction-building.md │ └── tags.yml ├── tsconfig.json ├── .gitignore ├── README.md ├── sidebars.ts └── package.json ├── .gitattributes ├── .prettierignore ├── examples ├── ethereum │ ├── blockchain │ │ ├── files │ │ │ ├── localtime │ │ │ └── genesis.json │ │ ├── images │ │ │ ├── 1627379241363.jpg │ │ │ └── 1627379455441.jpg │ │ ├── eth-netstats │ │ │ └── Dockerfile │ │ ├── attack │ │ │ ├── package.json │ │ │ └── rpc │ │ │ │ ├── miner.js │ │ │ │ ├── request.js │ │ │ │ ├── admin.js │ │ │ │ ├── personal.js │ │ │ │ └── eth.js │ │ ├── monitored-geth-client │ │ │ ├── start.sh │ │ │ ├── Dockerfile │ │ │ └── app.json │ │ ├── docs │ │ │ └── double-spent.md │ │ ├── README.MD │ │ └── docker-compose.yml │ ├── account │ │ ├── wallet.ts │ │ └── account.ts │ ├── multisig │ │ └── bitgo │ │ │ └── decode.js │ └── tx │ │ ├── decode.js │ │ ├── transaction.js │ │ └── erc20.js ├── solana │ ├── squads-v3 │ │ ├── README.MD │ │ └── get-pda.ts │ ├── squads-v4 │ │ ├── README.MD │ │ ├── get-pda.ts │ │ └── account.ts │ ├── account │ │ ├── signature.ts │ │ ├── get-banaces.ts │ │ └── address.ts │ ├── subscribes │ │ ├── initialize.ts │ │ └── wsol-usdc.ts │ ├── jupiter │ │ └── instruction.ts │ └── spl-token │ │ └── account.ts ├── bitcoin │ ├── utils │ │ └── crypto.ts │ ├── tx │ │ ├── btc.bitgo.v2.js │ │ ├── decode.js │ │ ├── btc.js │ │ ├── rbf.js │ │ ├── bitcoin.js │ │ └── bch.v1.js │ ├── blockchain │ │ └── docker-compose.yml │ ├── address │ │ ├── multisig.ts │ │ ├── address.spec.ts │ │ ├── legacy.ts │ │ └── address.ts │ ├── script.test.ts │ └── classify.test.ts ├── polkadot │ ├── account │ │ ├── keyring.js │ │ ├── verify.js │ │ ├── mnemonic.js │ │ └── multi.js │ ├── utils.js │ ├── old │ │ └── old.js │ ├── multisig │ │ └── fund.js │ └── sign.js ├── cardano │ └── tx │ │ └── submit.ts ├── crosschain │ └── anyswap │ │ ├── README.MD │ │ ├── abi.js │ │ ├── approve.js │ │ └── usdt.js ├── umi │ ├── account │ │ └── account.js │ └── tx │ │ └── tx.js ├── ripple │ ├── account │ │ ├── address.js │ │ └── check.js │ ├── tx │ │ ├── codec.js │ │ └── sign-external.js │ └── multisig │ │ ├── account.js │ │ └── enable.js ├── cosmos │ ├── account │ │ ├── address.js │ │ └── multisig.js │ └── tx │ │ └── decode.js ├── stellar │ ├── account │ │ └── index.js │ └── README.md ├── tron │ ├── tx │ │ └── decode.js │ └── account │ │ └── address.js ├── avalanche │ ├── account.js │ └── sign-external.js ├── ton │ └── wallet.ts └── aptos │ ├── transfer_coin.ts │ └── account.ts ├── pnpm-workspace.yaml ├── .hintrc ├── .prettierrc ├── tsconfig.json ├── vitest.config.mts ├── LICENSE ├── .github └── workflows │ └── deploy.yml ├── elliptic ├── curve25519.ts ├── ed25519.ts └── secp256k1.ts └── .gitignore /.nvmrc: -------------------------------------------------------------------------------- 1 | v20 2 | -------------------------------------------------------------------------------- /website/docs/bitcoin/FAQ.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /website/docs/ethereum/FAQ.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /website/examples: -------------------------------------------------------------------------------- 1 | ../examples -------------------------------------------------------------------------------- /website/static/.nojekyll: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.js filter=gitignore -------------------------------------------------------------------------------- /website/docs/ethereum/blockchain/README.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | README.md 3 | -------------------------------------------------------------------------------- /website/docs/ethereum/multisig/batch/README.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/ethereum/blockchain/files/localtime: -------------------------------------------------------------------------------- 1 | Asia/Shanghai 2 | -------------------------------------------------------------------------------- /website/static/robots.txt: -------------------------------------------------------------------------------- 1 | # Algolia-Crawler-Verif: 68A01B91A57A7B4B -------------------------------------------------------------------------------- /pnpm-workspace.yaml: -------------------------------------------------------------------------------- 1 | packages: 2 | - 'website' 3 | - 'packages/*' 4 | -------------------------------------------------------------------------------- /website/docs/bitcoin/tx/rbf.md: -------------------------------------------------------------------------------- 1 | ```ts file=/examples/bitcoin/tx/rbf.js 2 | ``` -------------------------------------------------------------------------------- /website/docs/bitcoin/tx/decode.md: -------------------------------------------------------------------------------- 1 | ```ts file=/examples/bitcoin/tx/decode.js 2 | ``` -------------------------------------------------------------------------------- /website/docs/ethereum/tx/erc20.md: -------------------------------------------------------------------------------- 1 | ```ts file=/examples/ethereum/tx/erc20.js 2 | ``` -------------------------------------------------------------------------------- /website/docs/bitcoin/utils/crypto.md: -------------------------------------------------------------------------------- 1 | ```ts file=/examples/bitcoin/utils/crypto.ts 2 | ``` -------------------------------------------------------------------------------- /website/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Allow: / 3 | 4 | # Algolia-Crawler-Verif: 8EC3DD2479BB15D9 -------------------------------------------------------------------------------- /website/docs/ethereum/tx/abi-decode.md: -------------------------------------------------------------------------------- 1 | ```ts file=/examples/ethereum/tx/abi-decode.js 2 | ``` -------------------------------------------------------------------------------- /website/docs/ethereum/multisig/safe/helper.md: -------------------------------------------------------------------------------- 1 | ```ts file=/examples/ethereum/multisig/safe/helper.ts 2 | ``` -------------------------------------------------------------------------------- /website/docs/ethereum/tx/abi-decode-erc721.md: -------------------------------------------------------------------------------- 1 | ```ts file=/examples/ethereum/tx/abi-decode-erc721.js 2 | ``` -------------------------------------------------------------------------------- /website/postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | '@tailwindcss/postcss': {}, 4 | }, 5 | }; 6 | -------------------------------------------------------------------------------- /website/docs/ethereum/multisig/safe/deploy.md: -------------------------------------------------------------------------------- 1 | ```ts file=/examples/ethereum/multisig/safe/deploy/web3.js 2 | ``` -------------------------------------------------------------------------------- /website/static/img/banner.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iamnivekx/blockchain-notes/HEAD/website/static/img/banner.jpg -------------------------------------------------------------------------------- /website/static/img/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iamnivekx/blockchain-notes/HEAD/website/static/img/favicon.ico -------------------------------------------------------------------------------- /website/static/img/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iamnivekx/blockchain-notes/HEAD/website/static/img/favicon-16x16.png -------------------------------------------------------------------------------- /website/static/img/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iamnivekx/blockchain-notes/HEAD/website/static/img/favicon-32x32.png -------------------------------------------------------------------------------- /.hintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "development" 4 | ], 5 | "hints": { 6 | "typescript-config/consistent-casing": "off" 7 | } 8 | } -------------------------------------------------------------------------------- /examples/ethereum/blockchain/images/1627379241363.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iamnivekx/blockchain-notes/HEAD/examples/ethereum/blockchain/images/1627379241363.jpg -------------------------------------------------------------------------------- /examples/ethereum/blockchain/images/1627379455441.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iamnivekx/blockchain-notes/HEAD/examples/ethereum/blockchain/images/1627379455441.jpg -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 140, 3 | "tabWidth": 2, 4 | "useTabs": false, 5 | "semi": true, 6 | "singleQuote": true, 7 | "trailingComma": "all" 8 | } 9 | -------------------------------------------------------------------------------- /website/docs/bitcoin/utils/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "工具函数", 3 | "position": 4, 4 | "link": { 5 | "type": "generated-index", 6 | "description": "比特币工具函数" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /examples/solana/squads-v3/README.MD: -------------------------------------------------------------------------------- 1 | # Squads Protocol V3 2 | 3 | - [squads-legacy](https://docs.squads.so/main/v/squads-legacy) 4 | - [squads-mpl](https://github.com/Squads-Protocol/squads-mpl) 5 | -------------------------------------------------------------------------------- /website/docs/cardano/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Cardano", 3 | "position": 4, 4 | "link": { 5 | "type": "generated-index", 6 | "description": "Cardano 区块链开发示例和指南" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /website/docs/cardano/tx/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "交易处理", 3 | "position": 2, 4 | "link": { 5 | "type": "generated-index", 6 | "description": "Cardano 交易构建、签名和提交" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /website/docs/cosmos/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Cosmos", 3 | "position": 5, 4 | "link": { 5 | "type": "generated-index", 6 | "description": "Cosmos 区块链开发示例和指南" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /website/docs/cosmos/tx/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "交易处理", 3 | "position": 2, 4 | "link": { 5 | "type": "generated-index", 6 | "description": "Cosmos 交易构建、签名和广播" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /website/docs/aptos/tx/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "交易处理", 3 | "position": 5, 4 | "link": { 5 | "type": "generated-index", 6 | "description": "Aptos交易处理指南,包括交易构建、签名和提交。" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /website/docs/bitcoin/address/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "地址管理", 3 | "position": 1, 4 | "link": { 5 | "type": "generated-index", 6 | "description": "比特币地址生成、验证和转换指南。" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /website/docs/bitcoin/tx/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "交易处理", 3 | "position": 3, 4 | "link": { 5 | "type": "generated-index", 6 | "description": "比特币交易构建、签名、解码和费用替换指南。" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /website/docs/cosmos/delegate/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "质押委托", 3 | "position": 3, 4 | "link": { 5 | "type": "generated-index", 6 | "description": "Cosmos 质押、委托和奖励管理" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /website/docs/cosmos/multisig/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "多重签名", 3 | "position": 4, 4 | "link": { 5 | "type": "generated-index", 6 | "description": "Cosmos 多重签名交易和账户管理" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /website/docs/crosschain/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "跨链技术", 3 | "position": 8, 4 | "link": { 5 | "type": "generated-index", 6 | "description": "学习如何使用各种协议和桥接实现跨链功能。" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /website/docs/ton/tx/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "交易处理", 3 | "position": 2, 4 | "link": { 5 | "type": "generated-index", 6 | "description": "TON 交易处理,包括交易构建、签名、发送和地址处理。" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /website/docs/aptos/nft/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "NFT功能", 3 | "position": 3, 4 | "link": { 5 | "type": "generated-index", 6 | "description": "Aptos NFT功能指南,包括NFT创建、管理和转账。" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /website/docs/bitcoin/script/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "脚本系统", 3 | "position": 2, 4 | "link": { 5 | "type": "generated-index", 6 | "description": "比特币脚本编程语言,包括编译、反编译和脚本分类。" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /website/docs/cardano/account/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "账户管理", 3 | "position": 1, 4 | "link": { 5 | "type": "generated-index", 6 | "description": "Cardano 账户创建、密钥管理和地址生成" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /website/docs/cosmos/account/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "账户管理", 3 | "position": 1, 4 | "link": { 5 | "type": "generated-index", 6 | "description": "Cosmos 账户创建、地址生成和多重签名" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /website/docs/ethereum/account/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "账户管理", 3 | "position": 1, 4 | "link": { 5 | "type": "generated-index", 6 | "description": "以太坊账户创建、管理和钱包集成指南。" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /website/docs/ton/account/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "账户管理", 3 | "position": 1, 4 | "link": { 5 | "type": "generated-index", 6 | "description": "TON 账户管理,包括私钥、公钥、地址生成和钱包操作。" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /website/docs/aptos/account/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "账户管理", 3 | "position": 1, 4 | "link": { 5 | "type": "generated-index", 6 | "description": "Aptos账户管理指南,包括账户创建、密钥管理和地址派生。" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /website/docs/aptos/multisig/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "多重签名", 3 | "position": 4, 4 | "link": { 5 | "type": "generated-index", 6 | "description": "Aptos多重签名指南,包括多签账户创建和多签交易构建。" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /website/docs/aptos/token/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "代币操作", 3 | "position": 2, 4 | "link": { 5 | "type": "generated-index", 6 | "description": "Aptos代币操作指南,包括代币转账、自定义代币创建和余额管理。" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /website/docs/ethereum/multisig/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "多重签名", 3 | "position": 3, 4 | "link": { 5 | "type": "generated-index", 6 | "description": "以太坊多重签名钱包和Gnosis Safe集成指南。" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /website/docs/stellar/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Stellar", 3 | "position": 13, 4 | "link": { 5 | "type": "generated-index", 6 | "description": "恒星区块链开发指南,包括账户管理、交易处理、代币发行和资产管理。" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /website/docs/ton/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "TON", 3 | "position": 12, 4 | "link": { 5 | "type": "generated-index", 6 | "description": "TON区块链开发指南,包括账户管理、交易处理、Jetton代币和智能合约开发。" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /website/docs/ton/token/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "代币操作", 3 | "position": 3, 4 | "link": { 5 | "type": "generated-index", 6 | "description": "TON 代币操作,包括 Jetton 代币的转账、授权和管理。" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /website/docs/tron/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Tron", 3 | "position": 12, 4 | "link": { 5 | "type": "generated-index", 6 | "description": "波场区块链开发指南,包括账户管理、交易处理、智能合约和代币应用开发。" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /website/docs/aptos/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Aptos", 3 | "position": 4, 4 | "link": { 5 | "type": "generated-index", 6 | "description": "Aptos区块链开发指南,包括账户管理、代币操作、NFT创建和多重签名交易。" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /website/docs/bitcoin/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Bitcoin", 3 | "position": 1, 4 | "link": { 5 | "type": "generated-index", 6 | "description": "比特币区块链开发指南,包括地址生成、脚本系统、交易构建和UTXO管理。" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /website/docs/ethereum/tx/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "交易处理", 3 | "position": 2, 4 | "link": { 5 | "type": "generated-index", 6 | "description": "以太坊交易构建、签名、发送和验证的完整指南。" 7 | } 8 | } 9 | 10 | -------------------------------------------------------------------------------- /website/docs/ripple/multisig/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "多重签名", 3 | "position": 3, 4 | "link": { 5 | "type": "generated-index", 6 | "description": "Ripple 多重签名功能指南,包括账户创建、交易处理和功能启用。" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /website/docs/ripple/tx/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "交易处理", 3 | "position": 2, 4 | "link": { 5 | "type": "generated-index", 6 | "description": "Ripple 交易创建、签名、提交和编码指南,包括在线和离线交易处理。" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /website/docs/solana/account/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "账户管理", 3 | "position": 1, 4 | "link": { 5 | "type": "generated-index", 6 | "description": "Solana账户管理指南,包括账户创建、密钥管理和地址派生。" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /website/docs/solana/token/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "代币操作", 3 | "position": 2, 4 | "link": { 5 | "type": "generated-index", 6 | "description": "Solana代币操作指南,包括SPL代币标准、代币转账和余额管理。" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /website/src/lib/utils.ts: -------------------------------------------------------------------------------- 1 | import { clsx, type ClassValue } from 'clsx' 2 | import { twMerge } from 'tailwind-merge' 3 | 4 | export function cn(...inputs: ClassValue[]) { 5 | return twMerge(clsx(inputs)) 6 | } 7 | -------------------------------------------------------------------------------- /website/blog/authors.yml: -------------------------------------------------------------------------------- 1 | iamnivekx: 2 | name: iamnivekx 3 | title: Blockchain Developer 4 | image_url: https://github.com/iamnivekx.png 5 | page: true 6 | socials: 7 | x: inivek3 8 | github: iamnivekx 9 | -------------------------------------------------------------------------------- /website/docs/ethereum/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Ethereum", 3 | "position": 2, 4 | "link": { 5 | "type": "generated-index", 6 | "description": "以太坊区块链开发指南,包括账户管理、交易处理、智能合约和DeFi应用开发。" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /website/docs/polkadot/batch/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "批量操作", 3 | "position": 4, 4 | "link": { 5 | "type": "generated-index", 6 | "description": "Polkadot 批量交易和操作指南,包括批量转账、条件批处理和费用优化策略。" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /website/docs/polkadot/tx/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "交易处理", 3 | "position": 2, 4 | "link": { 5 | "type": "generated-index", 6 | "description": "Polkadot 交易构建、签名、解码和离线处理指南,包括网络连接和交易参数配置。" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /website/docs/ripple/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Ripple", 3 | "position": 8, 4 | "link": { 5 | "type": "generated-index", 6 | "description": "Ripple 区块链开发指南,包括账户管理、交易处理、多重签名和 XRP 代币操作。" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /website/docs/ripple/account/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "账户管理", 3 | "position": 1, 4 | "link": { 5 | "type": "generated-index", 6 | "description": "Ripple 账户创建、管理和配置指南,包括地址生成、账户检查和启用。" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /website/docs/solana/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Solana", 3 | "position": 3, 4 | "link": { 5 | "type": "generated-index", 6 | "description": "Solana区块链开发指南,包括账户管理、SPL代币、DeFi集成和智能合约开发。" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /website/docs/solana/defi/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "DeFi集成", 3 | "position": 3, 4 | "link": { 5 | "type": "generated-index", 6 | "description": "Solana DeFi集成指南,包括Jupiter聚合器、Raydium等。" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /website/docs/solana/multisig/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "多重签名", 3 | "position": 4, 4 | "link": { 5 | "type": "generated-index", 6 | "description": "Solana多重签名解决方案,包括Squads v3和v4多签钱包管理。" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /website/docs/tron/account/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "账户管理", 3 | "position": 1, 4 | "link": { 5 | "type": "generated-index", 6 | "description": "学习如何创建、管理和使用 Tron 账户,包括地址生成、密钥管理和余额查询。" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /website/docs/avalanche/tx/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "交易操作", 3 | "position": 2, 4 | "link": { 5 | "type": "generated-index", 6 | "description": "学习如何在 Avalanche 上构建、签名和发送交易,包括资产转移、交易解码和批量操作。" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /website/docs/ethereum/multisig/safe/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Gnosis Safe", 3 | "position": 1, 4 | "link": { 5 | "type": "generated-index", 6 | "description": "Gnosis Safe多重签名钱包集成和操作指南。" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /website/docs/polkadot/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Polkadot", 3 | "position": 7, 4 | "link": { 5 | "type": "generated-index", 6 | "description": "Polkadot 区块链开发指南,包括账户管理、交易处理、多重签名、批量操作和质押功能。" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /website/docs/polkadot/staking/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "质押", 3 | "position": 5, 4 | "link": { 5 | "type": "generated-index", 6 | "description": "Polkadot 质押和验证人系统指南,包括质押操作、奖励管理、验证人选择和策略优化。" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /website/docs/solana/subscribes/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "订阅和监控", 3 | "position": 5, 4 | "link": { 5 | "type": "generated-index", 6 | "description": "Solana区块链事件订阅和实时监控,包括日志监听、账户变化和价格监控。" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /website/docs/stellar/account/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "账户管理", 3 | "position": 1, 4 | "link": { 5 | "type": "generated-index", 6 | "description": "学习如何创建、管理和使用 Stellar 账户,包括密钥生成、地址管理和余额查询。" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /website/docs/stellar/tx/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "交易处理", 3 | "position": 2, 4 | "link": { 5 | "type": "generated-index", 6 | "description": "学习如何构建、签名和发送 Stellar 交易,包括 XLM 转账、代币发行和资产管理。" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /website/docs/tron/tx/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "交易处理", 3 | "position": 2, 4 | "link": { 5 | "type": "generated-index", 6 | "description": "学习如何构建、签名和发送 Tron 交易,包括 TRX 转账、TRC10 和 TRC20 代币交易。" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /website/docs/avalanche/account/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "账户管理", 3 | "position": 1, 4 | "link": { 5 | "type": "generated-index", 6 | "description": "学习如何在 Avalanche 上创建和管理账户,包括密钥生成、地址管理和安全最佳实践。" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /website/docs/polkadot/account/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "账户管理", 3 | "position": 1, 4 | "link": { 5 | "type": "generated-index", 6 | "description": "Polkadot 账户创建、管理和密钥管理指南,包括助记词生成、密钥环配置和地址验证。" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /website/docs/crosschain/anyswap/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "AnySwap", 3 | "position": 1, 4 | "link": { 5 | "type": "generated-index", 6 | "description": "学习如何使用 AnySwap 进行跨链资产转移和桥接,包含实际代码示例和详细操作指南。" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /website/docs/polkadot/multisig/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "多重签名", 3 | "position": 3, 4 | "link": { 5 | "type": "generated-index", 6 | "description": "Polkadot 多重签名功能指南,包括账户创建、交易处理、质押额外代币、质押提名验证人、提名验证人和功能启用。" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /website/docs/avalanche/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Avalanche", 3 | "position": 6, 4 | "link": { 5 | "type": "generated-index", 6 | "description": "Avalanche 是一个高性能的区块链平台,支持智能合约和去中心化应用。学习如何使用 AvalancheJS 进行账户管理、交易签名和资产转移。" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /examples/solana/squads-v4/README.MD: -------------------------------------------------------------------------------- 1 | # Squads Protocol V4 2 | 3 | - [quickstart](https://docs.squads.so/main/v/development/introduction/quickstart) 4 | - [v4](https://github.com/Squads-Protocol/v4) 5 | - [v4-examples](https://github.com/Squads-Protocol/v4-examples) 6 | -------------------------------------------------------------------------------- /examples/ethereum/blockchain/eth-netstats/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:8-alpine 2 | 3 | RUN apk add --update git 4 | 5 | RUN git clone https://github.com/cubedro/eth-netstats 6 | 7 | WORKDIR /eth-netstats 8 | 9 | RUN npm install 10 | RUN npm install -g grunt-cli 11 | RUN grunt 12 | 13 | EXPOSE 3000 14 | 15 | CMD ["npm", "start"] -------------------------------------------------------------------------------- /website/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@docusaurus/tsconfig", 3 | "compilerOptions": { 4 | "jsx": "react", 5 | "strict": true, 6 | "forceConsistentCasingInFileNames": true, 7 | "baseUrl": ".", 8 | "paths": { 9 | "@/*": ["./src/*"] 10 | } 11 | }, 12 | "exclude": [".docusaurus", "build"] 13 | } 14 | -------------------------------------------------------------------------------- /website/.gitignore: -------------------------------------------------------------------------------- 1 | # Dependencies 2 | /node_modules 3 | 4 | # Production 5 | /build 6 | 7 | # Generated files 8 | .docusaurus 9 | .cache-loader 10 | 11 | # Misc 12 | .DS_Store 13 | .env.local 14 | .env.development.local 15 | .env.test.local 16 | .env.production.local 17 | 18 | npm-debug.log* 19 | yarn-debug.log* 20 | yarn-error.log* 21 | -------------------------------------------------------------------------------- /examples/ethereum/blockchain/attack/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ethereum-double-spent", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "node": "node index.js" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "node-fetch": "^2.6.1", 13 | "shelljs": "^0.8.4" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /examples/ethereum/blockchain/monitored-geth-client/start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | cd /root/eth-net-intelligence-api 4 | perl -pi -e "s/XXX/$(hostname)/g" app.json 5 | pm2 start ./app.json 6 | sleep 3 7 | geth --datadir=~/.ethereum/devchain init "/root/files/genesis.json" 8 | sleep 3 9 | BOOTSTRAP_IP=`getent hosts bootstrap | cut -d" " -f1` 10 | GETH_OPTS=${@/XXX/$BOOTSTRAP_IP} 11 | geth $GETH_OPTS -------------------------------------------------------------------------------- /website/blog/2024-01-20-ethereum-account.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 钱包和地址生成 3 | authors: [iamnivekx] 4 | tags: ['ethereum', 'account'] 5 | --- 6 | 7 | 8 | 9 | ## 生成私钥 10 | 11 | ```ts file=/examples/ethereum/account/wallet.ts showLineNumbers 12 | ``` 13 | 14 | ## 私钥生成地址 15 | 16 | ```ts file=/examples/ethereum/account/account.ts showLineNumbers 17 | ``` 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /website/docs/aptos/token/balance.md: -------------------------------------------------------------------------------- 1 | # 代币余额管理 2 | 3 | > TODO: 本文档正在编写中,将包含代币余额查询、管理和监控功能。 4 | 5 | ## 概述 6 | 7 | 代币余额管理是Aptos开发中的重要功能,包括: 8 | - 查询代币余额 9 | - 监控余额变化 10 | - 批量余额查询 11 | - 余额历史记录 12 | 13 | ## 待完成内容 14 | 15 | - [ ] 基础余额查询 16 | - [ ] 批量余额查询 17 | - [ ] 余额变化监控 18 | - [ ] 余额历史记录 19 | - [ ] 余额统计功能 20 | 21 | ## 参考资源 22 | 23 | - [Aptos代币标准](https://aptos.dev/guides/coin-and-token) 24 | - [Aptos SDK文档](https://aptos-labs.github.io/ts-sdk-doc/) 25 | -------------------------------------------------------------------------------- /website/docs/aptos/tx/transaction.md: -------------------------------------------------------------------------------- 1 | # 交易构建 2 | 3 | > TODO: 本文档正在编写中,将包含交易创建、构建和签名功能。 4 | 5 | ## 概述 6 | 7 | 交易构建是Aptos开发的核心功能,包括: 8 | - 创建交易payload 9 | - 设置交易参数 10 | - 交易签名 11 | - 交易验证 12 | 13 | ## 待完成内容 14 | 15 | - [ ] 基础交易构建 16 | - [ ] 交易payload创建 17 | - [ ] 交易参数设置 18 | - [ ] 交易签名 19 | - [ ] 交易验证 20 | 21 | ## 参考资源 22 | 23 | - [Aptos交易指南](https://aptos.dev/build/guides/first-transaction) 24 | - [Aptos SDK文档](https://aptos-labs.github.io/ts-sdk-doc/) 25 | -------------------------------------------------------------------------------- /website/docs/aptos/tx/submit.md: -------------------------------------------------------------------------------- 1 | # 交易提交 2 | 3 | > TODO: 本文档正在编写中,将包含交易广播、确认和状态监控功能。 4 | 5 | ## 概述 6 | 7 | 交易提交是交易生命周期的最后阶段,包括: 8 | - 交易广播 9 | - 交易确认 10 | - 状态监控 11 | - 错误处理 12 | 13 | ## 待完成内容 14 | 15 | - [ ] 交易广播 16 | - [ ] 交易确认等待 17 | - [ ] 交易状态监控 18 | - [ ] 错误处理 19 | - [ ] 交易重试 20 | 21 | ## 参考资源 22 | 23 | - [Aptos交易提交](https://aptos.dev/build/guides/first-transaction#5-signing-and-submitting-the-transaction) 24 | - [Aptos浏览器](https://explorer.aptoslabs.com/) 25 | -------------------------------------------------------------------------------- /website/docs/aptos/nft/nft.md: -------------------------------------------------------------------------------- 1 | # NFT创建 2 | 3 | > TODO: 本文档正在编写中,将包含NFT集合创建、NFT铸造和管理功能。 4 | 5 | ## 概述 6 | 7 | NFT(非同质化代币)是Aptos生态系统中的重要组成部分,包括: 8 | - 创建NFT集合 9 | - 铸造NFT代币 10 | - 管理NFT元数据 11 | - NFT属性设置 12 | 13 | ## 待完成内容 14 | 15 | - [ ] 创建NFT集合 16 | - [ ] 铸造NFT代币 17 | - [ ] 设置NFT属性 18 | - [ ] 管理NFT元数据 19 | - [ ] NFT批量操作 20 | 21 | ## 参考资源 22 | 23 | - [Aptos NFT指南](https://aptos.dev/build/guides/your-first-nft) 24 | - [Aptos SDK文档](https://aptos.dev/build/sdks/ts-sdk) 25 | -------------------------------------------------------------------------------- /examples/ethereum/blockchain/attack/rpc/miner.js: -------------------------------------------------------------------------------- 1 | const { request } = require('./request'); 2 | 3 | async function miner_stop(uri) { 4 | return request(uri, 'miner_stop'); 5 | } 6 | 7 | // 8 | async function miner_start(uri, number) { 9 | return request(uri, 'miner_start', number ? [number] : []); 10 | } 11 | 12 | async function miner_stop(uri) { 13 | return request(uri, 'miner_stop'); 14 | } 15 | 16 | exports.miner_start = miner_start; 17 | exports.miner_stop = miner_stop; 18 | -------------------------------------------------------------------------------- /examples/ethereum/blockchain/monitored-geth-client/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ethereum/client-go:v1.10.14 2 | 3 | RUN apk add --update git bash nodejs npm perl 4 | 5 | RUN cd /root &&\ 6 | git clone https://github.com/cubedro/eth-net-intelligence-api &&\ 7 | cd eth-net-intelligence-api &&\ 8 | npm install &&\ 9 | npm install -g pm2 10 | 11 | ADD start.sh /root/start.sh 12 | ADD app.json /root/eth-net-intelligence-api/app.json 13 | RUN chmod +x /root/start.sh 14 | 15 | ENTRYPOINT /root/start.sh -------------------------------------------------------------------------------- /examples/bitcoin/utils/crypto.ts: -------------------------------------------------------------------------------- 1 | import createHash from 'create-hash'; 2 | 3 | export function ripemd160(buffer: Buffer) { 4 | try { 5 | return createHash('ripemd160').update(buffer).digest(); 6 | } catch (err) { 7 | return createHash('rmd160').update(buffer).digest(); 8 | } 9 | }; 10 | 11 | export function sha256(buffer: Buffer) { 12 | return createHash('sha256').update(buffer).digest(); 13 | } 14 | 15 | 16 | export function sha256x2(buffer: Buffer) { 17 | return sha256(sha256(buffer)); 18 | }; 19 | -------------------------------------------------------------------------------- /examples/ethereum/account/wallet.ts: -------------------------------------------------------------------------------- 1 | import { ethers } from 'ethers'; 2 | 3 | // https://docs.ethers.org/v5/api/signer/#Wallet 4 | async function main() { 5 | const wallet = ethers.Wallet.createRandom(); 6 | console.log('address : ', await wallet.getAddress()); 7 | console.log('public key : ', wallet.publicKey); 8 | console.log('compressed : ', ethers.utils.computePublicKey(wallet.publicKey, true)); 9 | console.log('private key : ', wallet.privateKey); 10 | } 11 | 12 | main().catch(console.error); 13 | 14 | -------------------------------------------------------------------------------- /website/docs/aptos/multisig/account.md: -------------------------------------------------------------------------------- 1 | # 多重签名账户 2 | 3 | > TODO: 本文档正在编写中,将包含多重签名账户创建和管理功能。 4 | 5 | ## 概述 6 | 7 | 多重签名账户是Aptos安全功能的重要组成部分,包括: 8 | - 多签账户创建 9 | - 签名者管理 10 | - 阈值设置 11 | - 账户配置 12 | 13 | ## 待完成内容 14 | 15 | - [ ] 多签账户创建 16 | - [ ] 签名者添加/移除 17 | - [ ] 阈值修改 18 | - [ ] 账户配置管理 19 | - [ ] 权限控制 20 | 21 | ## 参考资源 22 | 23 | - [Aptos多重签名](https://aptos.dev/guides/accounts#multi-signature-accounts) 24 | - [Aptos账户管理](https://aptos.dev/guides/accounts) 25 | - [Aptos SDK文档](https://aptos-labs.github.io/ts-sdk-doc/) 26 | -------------------------------------------------------------------------------- /website/docs/aptos/nft/transfer.md: -------------------------------------------------------------------------------- 1 | # NFT转账 2 | 3 | > TODO: 本文档正在编写中,将包含NFT所有权转移和交易功能。 4 | 5 | ## 概述 6 | 7 | NFT转账是NFT生态系统的核心功能,包括: 8 | - NFT所有权转移 9 | - 批量NFT转账 10 | - 条件NFT转账 11 | - 转账历史记录 12 | 13 | ## 待完成内容 14 | 15 | - [ ] 基础NFT转账 16 | - [ ] 批量NFT转账 17 | - [ ] 条件NFT转账 18 | - [ ] 转账验证 19 | - [ ] 转账历史查询 20 | 21 | ## 参考资源 22 | 23 | ## 参考资源 24 | 25 | - [Aptos NFT标准](https://aptos.dev/build/guides/your-first-nft) 26 | - [Aptos Token模块](https://aptos.dev/move-reference/mainnet/aptos-token) 27 | - [Aptos SDK文档](https://aptos.dev/build/sdks/ts-sdk) 28 | -------------------------------------------------------------------------------- /examples/ethereum/blockchain/monitored-geth-client/app.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "node-app", 4 | "script": "app.js", 5 | "log_date_format": "YYYY-MM-DD HH:mm Z", 6 | "merge_logs": false, 7 | "watch": false, 8 | "max_restarts": 10, 9 | "exec_interpreter": "node", 10 | "exec_mode": "fork_mode", 11 | "env": { 12 | "NODE_ENV": "production", 13 | "RPC_HOST": "localhost", 14 | "RPC_PORT": "8545", 15 | "LISTENING_PORT": "30303", 16 | "INSTANCE_NAME": "XXX", 17 | "WS_SERVER": "ws://netstats:3000", 18 | "WS_SECRET": "eth-net-stats-secret", 19 | "VERBOSITY": 2 20 | } 21 | } 22 | ] -------------------------------------------------------------------------------- /examples/ethereum/blockchain/attack/rpc/request.js: -------------------------------------------------------------------------------- 1 | const fetch = require('node-fetch'); 2 | 3 | function request(uri, method, params, id) { 4 | const body = { 5 | jsonrpc: '2.0', 6 | id: id || Date.now(), 7 | method, 8 | params, 9 | }; 10 | return fetch(uri, { 11 | method: 'post', 12 | body: JSON.stringify(body), 13 | headers: { 'Content-Type': 'application/json' }, 14 | }) 15 | .then((res) => res.json()) 16 | .then((res) => { 17 | const { error, result } = res; 18 | if (error) throw error; 19 | return result; 20 | }); 21 | } 22 | 23 | exports.request = request; 24 | -------------------------------------------------------------------------------- /examples/solana/account/signature.ts: -------------------------------------------------------------------------------- 1 | import { Keypair } from '@solana/web3.js'; 2 | import bs58 from 'bs58'; 3 | import nacl from 'tweetnacl'; 4 | import { bytesToHex, hexToBytes } from '@noble/hashes/utils'; 5 | import 'dotenv/config'; 6 | 7 | function main() { 8 | const secretKey = process.env.SOL_SECRET_KEY!; 9 | if (!secretKey) { 10 | throw new Error('SOL_SECRET_KEY is not set'); 11 | } 12 | const keypair = Keypair.fromSecretKey(bs58.decode(secretKey)); 13 | const message = hexToBytes('hello world'); 14 | const signature = nacl.sign.detached(message, keypair.secretKey); 15 | console.log('signature : ', bytesToHex(signature)); 16 | console.log('bs58 : ', bs58.encode(signature)); 17 | } 18 | 19 | main(); 20 | -------------------------------------------------------------------------------- /examples/bitcoin/tx/btc.bitgo.v2.js: -------------------------------------------------------------------------------- 1 | require('dotenv').config(); 2 | const { bitgo, networks, ECPair } = require('@bitgo/utxo-lib-v2'); 3 | 4 | const network = networks.testnet; 5 | 6 | var secret = process.env.ECDSA_SECRET; 7 | const signer = ECPair.fromPrivateKey(Buffer.from(secret, 'hex'), { network }); 8 | 9 | var txb = bitgo.createTransactionBuilderForNetwork(network); 10 | txb.addInput('fb3e300435a7fa7713a6e46b497342ac1c127d208d348cbf9813dc62e4fee435', 0); 11 | txb.addOutput('n1cScasu6XVoDki38WYAJH4ZJGRAfG8XRN', 9800); 12 | 13 | txb.sign(0, signer); 14 | 15 | var tx = txb.build(); 16 | var txId = tx.getId(); 17 | var txHex = tx.toHex(); 18 | 19 | console.log('bitgo txId : ', txId); 20 | console.log('bitgo hex : ', txHex); 21 | -------------------------------------------------------------------------------- /examples/polkadot/account/keyring.js: -------------------------------------------------------------------------------- 1 | const { stringToU8a, u8aToHex } = require('@polkadot/util'); 2 | const { cryptoWaitReady } = require('@polkadot/util-crypto'); 3 | const { Keyring } = require('@polkadot/keyring'); 4 | 5 | async function main() { 6 | await cryptoWaitReady(); 7 | 8 | const keyring = new Keyring(); 9 | const alice = keyring.addFromUri('//Alice'); 10 | 11 | // create the message, actual signature and verify 12 | const message = stringToU8a('message'); 13 | const signature = alice.sign(message); 14 | const isValid = alice.verify(message, signature); 15 | 16 | // output the result 17 | console.log(`${u8aToHex(signature)} is ${isValid ? 'valid' : 'invalid'}`); 18 | } 19 | 20 | main().then().catch(console.error); 21 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "declaration": true, 5 | "esModuleInterop": true, 6 | "removeComments": true, 7 | "emitDecoratorMetadata": true, 8 | "experimentalDecorators": true, 9 | "allowSyntheticDefaultImports": true, 10 | "target": "es2020", 11 | "sourceMap": true, 12 | "outDir": "./dist", 13 | "baseUrl": "./", 14 | "incremental": true, 15 | "skipLibCheck": true, 16 | "strictNullChecks": false, 17 | "noImplicitAny": false, 18 | "strictBindCallApply": false, 19 | "forceConsistentCasingInFileNames": false, 20 | "noFallthroughCasesInSwitch": false, 21 | "moduleResolution": "node", 22 | "resolveJsonModule": true 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /examples/ethereum/blockchain/attack/rpc/admin.js: -------------------------------------------------------------------------------- 1 | const { request } = require('./request'); 2 | 3 | // https://geth.ethereum.org/docs/rpc/ns-admin#admin_addpeer 4 | async function admin_addPeer(uri, peer) { 5 | return request(uri, 'admin_addPeer', [peer]); 6 | } 7 | 8 | async function admin_removePeer(uri, peer) { 9 | return request(uri, 'admin_removePeer', [peer]); 10 | } 11 | 12 | async function admin_nodeInfo(uri) { 13 | return request(uri, 'admin_nodeInfo'); 14 | } 15 | 16 | async function admin_peers(uri) { 17 | return request(uri, 'admin_peers'); 18 | } 19 | 20 | exports.admin_addPeer = admin_addPeer; 21 | exports.admin_removePeer = admin_removePeer; 22 | exports.admin_peers = admin_peers; 23 | exports.admin_nodeInfo = admin_nodeInfo; 24 | -------------------------------------------------------------------------------- /examples/ethereum/blockchain/attack/rpc/personal.js: -------------------------------------------------------------------------------- 1 | const { request } = require('./request'); 2 | 3 | // https://geth.ethereum.org/docs/rpc/ns-personal 4 | async function personal_importRawKey(uri, key, password) { 5 | return request(uri, 'personal_importRawKey', [key, password]); 6 | } 7 | 8 | async function personal_listAccounts(uri) { 9 | return request(uri, 'personal_listAccounts'); 10 | } 11 | 12 | async function personal_unlockAccount(uri, address, passphrase, duration) { 13 | return request(uri, 'personal_unlockAccount', [address, passphrase, duration]); 14 | } 15 | 16 | exports.personal_importRawKey = personal_importRawKey; 17 | exports.personal_listAccounts = personal_listAccounts; 18 | exports.personal_unlockAccount = personal_unlockAccount; 19 | -------------------------------------------------------------------------------- /examples/bitcoin/blockchain/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3.8' 2 | services: 3 | first-node: &node 4 | image: ruimarinho/bitcoin-core 5 | volumes: 6 | - ${PWD}/data/first:/home/bitcoin/.bitcoin 7 | # - ${PWD}/config/bitcoin.conf:/home/bitcoin/bitcoin.conf 8 | env_file: .env 9 | ports: 10 | - 18443:18443 11 | - 18444:18444 12 | # command: 'bitcoind -printtoconsole -conf=/home/bitcoin/bitcoin.conf' 13 | command: "bitcoind -printtoconsole \ 14 | -regtest=1 \ 15 | -rpcallowip=0.0.0.0/24 \ 16 | -rpcbind=0.0.0.0 \ 17 | -rpcauth=${RPC_AUTH}" 18 | 19 | second-node: 20 | <<: *node 21 | ports: 22 | - 28443:18443 23 | - 28444:18444 24 | volumes: 25 | - ${PWD}/data/second:/home/bitcoin/.bitcoin 26 | -------------------------------------------------------------------------------- /examples/ethereum/multisig/bitgo/decode.js: -------------------------------------------------------------------------------- 1 | const input = 2 | '0x39125215000000000000000000000000370ba1dc25c07d0c77ba9b83fcc75fcc2a0ac24300000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000060e3ed2c000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'; 3 | const abi = require('../abis/multisig'); 4 | const abiDecoder = require('abi-decoder'); 5 | abiDecoder.addABI(abi); 6 | const decodedData = abiDecoder.decodeMethod(input); 7 | console.log('decodedData', decodedData); 8 | -------------------------------------------------------------------------------- /examples/cardano/tx/submit.ts: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | import { Seed, WalletServer } from 'cardano-wallet-js'; 3 | 4 | async function main() { 5 | // let recoveryPhrase = Seed.generateRecoveryPhrase(); 6 | // console.log('recoveryPhrase: ', recoveryPhrase); 7 | // let mnemonic_sentence = Seed.toMnemonicList(recoveryPhrase); 8 | // let passphrase = 'tangocrypto'; 9 | // let name = 'namet'; 10 | 11 | const buffer = Buffer.from('0x....', 'hex'); 12 | const response = await axios({ 13 | headers: { 14 | 'Content-Type': 'application/cbor', 15 | }, 16 | method: 'post', 17 | url: 'https://submit-api.testnet.dandelion.link/api/submit/tx', 18 | data: buffer, 19 | }); 20 | console.log(response); 21 | return; 22 | } 23 | 24 | main().catch(console.error); 25 | -------------------------------------------------------------------------------- /examples/crosschain/anyswap/README.MD: -------------------------------------------------------------------------------- 1 | # AnySwap 2 | 3 | ## Router 4 | 5 | - [Router v3](https://bridgeapi.anyswap.exchange/v3/serverinfoV3?chainId=all&version=all) 6 | - [How-to-integrate-AnySwap-Router](https://github.com/anyswap/CrossChain-Router/wiki/How-to-integrate-AnySwap-Router) 7 | 8 | ## Bridge 9 | 10 | - [Bridge v2](https://bridgeapi.anyswap.exchange/v2/serverInfo/chainid) 11 | - [Bridge api for frontend](https://github.com/anyswap/CrossChain-Bridge/wiki/Bridge-api-for-frontend) 12 | 13 | ## MultiChain Bridge for Projects + Listing from 14 | 15 | - [how-to-apply-for-cross-chain-bridges-on-anyswap](https://medium.com/multichainorg/how-to-apply-for-cross-chain-bridges-on-anyswap-82fcb6c9f0d2) 16 | - [anyswap-fees-explained](https://medium.com/multichainorg/anyswap-fees-explained-bceddf535b83) -------------------------------------------------------------------------------- /vitest.config.mts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vitest/config'; 2 | 3 | export default defineConfig({ 4 | test: { 5 | projects: [ 6 | // you can use a list of glob patterns to define your projects 7 | // Vitest expects a list of config files 8 | // or directories where there is a config file 9 | 'packages/*', 10 | 'tests/*/vitest.config.{e2e,unit}.ts', 11 | // you can even run the same tests, 12 | // but with different configs in the same "vitest" process 13 | { 14 | test: { 15 | name: 'node', 16 | root: './examples', 17 | environment: 'node', 18 | include: ['**/*.{test,spec}.{js,ts}'], 19 | exclude: ['node_modules', 'dist', 'website'], 20 | }, 21 | }, 22 | ], 23 | }, 24 | }); 25 | -------------------------------------------------------------------------------- /examples/umi/account/account.js: -------------------------------------------------------------------------------- 1 | require('dotenv').config(); 2 | const umi = require('@umi-top/umi-core-js'); 3 | var mnemonic = process.env.UMI_MNEMONIC; 4 | 5 | const bip39 = require('bip39'); 6 | 7 | // var mnemonic = bip39.generateMnemonic(256); 8 | 9 | const seed = bip39.mnemonicToSeedSync(mnemonic); 10 | 11 | const secretKey = umi.SecretKey.fromSeed(seed); 12 | const publicKey = secretKey.getPublicKey(); 13 | const address1 = umi.Address.fromKey(secretKey); 14 | const address2 = umi.Address.fromKey(publicKey); 15 | 16 | console.log('mnemonic : ', mnemonic); 17 | console.log('private : ', umi.hexEncode(secretKey.getBytes())); 18 | console.log('public : ', umi.hexEncode(publicKey.getBytes())); 19 | console.log('address1 : ', address1.getBech32()); 20 | console.log('address2 : ', address2.getBech32()); 21 | -------------------------------------------------------------------------------- /examples/bitcoin/tx/decode.js: -------------------------------------------------------------------------------- 1 | const { networks, bitgo } = require('@bitgo/utxo-lib-v2'); 2 | const network = networks.testnet; 3 | 4 | const serialized = '0100000001db28cf6161bf01c2db9b2ca549afafaec57bb5a4447fd5f642bf6e2234d02d9a000000006b4830450221009f52b40dd697e9f7d2ea4b4c54e6e5870e4b472812bb6f80a8abdc598183408e02204046bc67052f8cb2e59e5df88d45f9670820b1113aa703fcf5817c0e7e8099b6012102bca8e21b7597c10b51b910f78cadfa42cf969e4a81e7e1a1597f673b813f32cdffffffff021d220000000000001976a9141c71691a111fbc17d978ff92aba0c00825cbd63588acdd020000000000001976a9141c71691a111fbc17d978ff92aba0c00825cbd63588ac00000000'; 5 | 6 | const tx = bitgo.createTransactionFromHex(serialized, network); 7 | const txb = bitgo.createTransactionBuilderFromTransaction(tx); 8 | 9 | const build = txb.build(); 10 | console.log('hash : ', build.getId()); 11 | -------------------------------------------------------------------------------- /website/docs/crosschain/anyswap/intro.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: AnySwap 介绍 3 | description: 了解 AnySwap,一个去中心化的跨链桥接协议 4 | --- 5 | 6 | # AnySwap 介绍 7 | 8 | AnySwap 是一个去中心化的跨链桥接协议,使用户能够在不同的区块链网络之间转移资产。它支持包括以太坊、BSC、Polygon、Avalanche 等在内的多条链。 9 | 10 | ## 主要特性 11 | 12 | - **多链支持**:桥接 20+ 个区块链网络 13 | - **去中心化**:无单点故障 14 | - **快速转移**:快速的跨链交易 15 | - **低费用**:具有竞争力的桥接成本 16 | - **广泛的代币支持**:ERC-20、BEP-20 和其他代币标准 17 | 18 | ## 工作原理 19 | 20 | 1. **锁定**:资产在源链上被锁定 21 | 2. **验证**:跨链验证者验证交易 22 | 3. **铸造**:在目标链上铸造等值代币 23 | 4. **销毁**:桥接回来时销毁原始代币 24 | 25 | ## 支持的网络 26 | 27 | - 以太坊主网 28 | - 币安智能链 (BSC) 29 | - Polygon 30 | - Avalanche 31 | - Fantom 32 | - Arbitrum 33 | - Optimism 34 | - 以及更多... 35 | 36 | ## 开始使用 37 | 38 | 要使用 AnySwap,你需要: 39 | - 源链上有资金的钱包 40 | - 目标链的原生代币用于支付 gas 费用 41 | - 了解桥接过程和费用 42 | 43 | ## 安全性 44 | 45 | AnySwap 使用验证者网络来保护跨链交易。该协议已经过审计,在 DeFi 生态系统中被广泛使用。 46 | -------------------------------------------------------------------------------- /examples/polkadot/account/verify.js: -------------------------------------------------------------------------------- 1 | const { stringToU8a, u8aToHex } = require('@polkadot/util'); 2 | const { cryptoWaitReady } = require('@polkadot/util-crypto'); 3 | const { Keyring } = require('@polkadot/keyring'); 4 | 5 | function verify() { 6 | const keyring = new Keyring(); 7 | 8 | // create Alice based on the development seed 9 | const alice = keyring.addFromUri('//Alice'); 10 | 11 | // create the message, actual signature and verify 12 | const message = stringToU8a('this is our message'); 13 | const signature = alice.sign(message); 14 | const isValid = alice.verify(message, signature); 15 | 16 | // output the result 17 | console.log(`${u8aToHex(signature)} is ${isValid ? 'valid' : 'invalid'}`); 18 | } 19 | 20 | async function main() { 21 | await cryptoWaitReady(); 22 | 23 | verify(); 24 | } 25 | 26 | main().then().catch(console.error); 27 | -------------------------------------------------------------------------------- /website/docs/crosschain/intro.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 跨链技术介绍 3 | description: 了解跨链桥接协议和在不同区块链间转移资产的解决方案 4 | --- 5 | 6 | # 跨链技术介绍 7 | 8 | 跨链技术使数字资产和数据能够在不同区块链网络之间转移。这对于实现真正的区块链互操作性和扩展去中心化应用的实用性至关重要。 9 | 10 | ## 什么是跨链? 11 | 12 | 跨链是指将资产或数据从一个区块链转移到另一个区块链的能力。这包括: 13 | 14 | - **资产转移**:将代币从一条链转移到另一条链 15 | - **数据桥接**:在不同区块链间共享信息 16 | - **跨链智能合约**:执行跨越多个链的逻辑 17 | 18 | ## 常见应用场景 19 | 20 | - **DeFi**:访问多个链上的流动性 21 | - **NFT**:在不同网络间移动数字收藏品 22 | - **游戏**:跨链资产可移植性 23 | - **企业**:多链业务运营 24 | 25 | ## 流行的跨链协议 26 | 27 | - **AnySwap/MultiChain**:多链桥接协议 28 | - **LayerZero**:全链互操作性协议 29 | - **Wormhole**:跨链消息传递协议 30 | - **Polygon Bridge**:以太坊到 Polygon 的桥接 31 | - **Binance Bridge**:BSC 到其他链的桥接 32 | 33 | ## 安全考虑 34 | 35 | - **验证者网络**:了解安全模型 36 | - **流动性池**:确保桥接有足够的流动性 37 | - **智能合约审计**:验证桥接安全性 38 | - **中心化风险**:评估协议治理 39 | 40 | ## 开始使用 41 | 42 | 根据你的需求选择合适的跨链协议,从简单的资产转移开始。始终先在测试网上测试,并了解所涉及的费用和确认时间。 43 | -------------------------------------------------------------------------------- /website/static/icons/avax.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 9 | 10 | 13 | 14 | -------------------------------------------------------------------------------- /website/static/icons/eth.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /examples/bitcoin/tx/btc.js: -------------------------------------------------------------------------------- 1 | require('dotenv').config(); 2 | 3 | const { TransactionBuilder, networks, ECPair } = require('@bitgo/utxo-lib'); 4 | const { payments } = require('@bitgo/utxo-lib-v2'); 5 | const network = networks.testnet; 6 | 7 | var secret = process.env.ECDSA_SECRET; 8 | 9 | const signer = ECPair.fromPrivateKeyBuffer(Buffer.from(secret, 'hex'), network); 10 | const pubkey = signer.getPublicKeyBuffer(); 11 | 12 | console.log('pubkey : ', pubkey.toString('hex')); 13 | const { address } = payments.p2pkh({ pubkey, network }); 14 | console.log('address : ', address); 15 | 16 | const txb = new TransactionBuilder(network); 17 | 18 | txb.addInput('fb3e300435a7fa7713a6e46b497342ac1c127d208d348cbf9813dc62e4fee435', 0); 19 | 20 | txb.addOutput('n1cScasu6XVoDki38WYAJH4ZJGRAfG8XRN', 9800); 21 | 22 | txb.sign(0, signer); 23 | 24 | const serialized = txb.build().toHex(); 25 | console.log('serialized : ', serialized); 26 | -------------------------------------------------------------------------------- /examples/solana/squads-v4/get-pda.ts: -------------------------------------------------------------------------------- 1 | import 'dotenv/config'; 2 | import { clusterApiUrl, Connection, PublicKey } from '@solana/web3.js'; 3 | import * as multisig from '@sqds/multisig'; 4 | 5 | const { Multisig } = multisig.accounts; 6 | 7 | // Cluster Connection 8 | var url = clusterApiUrl('devnet'); 9 | console.log('url : ', url); 10 | var connection = new Connection(url, 'confirmed'); 11 | 12 | async function main() { 13 | const createAddress = 'Hgucdc61K96b5Vs6PSEe2Sat9w7jKXMJmr6mkJVXXEqk'; 14 | const createKey = new PublicKey(createAddress); 15 | const [multisigPda] = multisig.getMultisigPda({ 16 | createKey, 17 | }); 18 | 19 | const multisigAccount = await Multisig.fromAccountAddress(connection, multisigPda); 20 | 21 | // Log out the multisig's members 22 | console.log('Members', multisigAccount.members); 23 | } 24 | 25 | try { 26 | main(); 27 | } catch (e) { 28 | console.error(e); 29 | } 30 | -------------------------------------------------------------------------------- /examples/ripple/account/address.js: -------------------------------------------------------------------------------- 1 | const { classicAddressToXAddress } = require('ripple-address-codec'); 2 | const RippleAPI = require('ripple-lib').RippleAPI; 3 | 4 | const api = new RippleAPI({}); 5 | 6 | // rsuUYDM8d15J44pZbdKumiDcnXHjPEuhXE 7 | // sapyGYwE3bh3JiYU59hFdecU2PovC 8 | 9 | // r9jhVPMfEWv2YCP7TNKoqyPUScUt66Hkuq 10 | // snv63YPxpLsqn7NsdGxnqECviNPZ2 11 | 12 | const secret = 'sapyGYwE3bh3JiYU59hFdecU2PovC'; 13 | const keypair = api.deriveKeypair(secret); 14 | const { publicKey, privateKey } = keypair; 15 | const address = api.deriveAddress(publicKey); 16 | console.log('publicKey : ', publicKey); 17 | console.log('privateKey : ', privateKey); 18 | const xAddress = classicAddressToXAddress(address, false, true); 19 | const xTestAddress = classicAddressToXAddress(address, false, false); 20 | console.log('address : ', address); 21 | console.log('x Addr : ', xAddress); 22 | console.log('x TestAddr : ', xTestAddress); 23 | -------------------------------------------------------------------------------- /examples/solana/subscribes/initialize.ts: -------------------------------------------------------------------------------- 1 | import { Connection, PublicKey } from '@solana/web3.js'; 2 | 3 | function onLogs(conn: Connection, poolId: PublicKey) { 4 | conn.onLogs( 5 | poolId, 6 | ({ err, logs, signature }) => { 7 | if (err) return; 8 | if (logs && logs.some((log) => log.includes('initialize') || log.includes('initialize2'))) { 9 | console.log(`Raydium Liquidity Pool initialized: https://solscan.io/tx/${signature}`); 10 | } 11 | console.log(logs); 12 | }, 13 | 'confirmed', 14 | ); 15 | } 16 | 17 | function main() { 18 | const url = process.env.SOLANA_RPC_URL!; 19 | const conn = new Connection(url, { 20 | commitment: 'confirmed', 21 | wsEndpoint: process.env.SOLANA_WS_URL!, 22 | }); 23 | 24 | // Raydium Liquidity Pool V4 25 | const poolId = new PublicKey('675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8'); 26 | onLogs(conn, poolId); 27 | } 28 | 29 | main(); 30 | -------------------------------------------------------------------------------- /examples/solana/squads-v3/get-pda.ts: -------------------------------------------------------------------------------- 1 | import dotenv from 'dotenv'; 2 | import { clusterApiUrl, Connection, PublicKey } from '@solana/web3.js'; 3 | import * as multisig from '@sqds/multisig'; 4 | dotenv.config(); 5 | 6 | const { Multisig } = multisig.accounts; 7 | 8 | // Cluster Connection 9 | var url = clusterApiUrl('devnet'); 10 | console.log('url : ', url); 11 | var connection = new Connection(url, 'confirmed'); 12 | 13 | async function main() { 14 | const createAddress = 'Hgucdc61K96b5Vs6PSEe2Sat9w7jKXMJmr6mkJVXXEqk'; 15 | const createKey = new PublicKey(createAddress); 16 | const [multisigPda] = multisig.getMultisigPda({ 17 | createKey, 18 | }); 19 | 20 | const multisigAccount = await Multisig.fromAccountAddress(connection, multisigPda); 21 | 22 | // Log out the multisig's members 23 | console.log('Members : ', multisigAccount.members); 24 | } 25 | 26 | try { 27 | main(); 28 | } catch (e) { 29 | console.error(e); 30 | } 31 | -------------------------------------------------------------------------------- /website/README.md: -------------------------------------------------------------------------------- 1 | # Website 2 | 3 | This website is built using [Docusaurus](https://docusaurus.io/), a modern static website generator. 4 | 5 | ## Installation 6 | 7 | ```bash 8 | yarn 9 | ``` 10 | 11 | ## Local Development 12 | 13 | ```bash 14 | pnpm run start 15 | ``` 16 | 17 | This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server. 18 | 19 | ## Build 20 | 21 | ```bash 22 | pnpm run build 23 | ``` 24 | 25 | This command generates static content into the `build` directory and can be served using any static contents hosting service. 26 | 27 | ## Deployment 28 | 29 | Using SSH: 30 | 31 | ```bash 32 | USE_SSH=true pnpm run deploy 33 | ``` 34 | 35 | Not using SSH: 36 | 37 | ```bash 38 | GIT_USER= pnpm run deploy 39 | ``` 40 | 41 | If you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the `gh-pages` branch. 42 | -------------------------------------------------------------------------------- /website/static/icons/gswap.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 7 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /examples/polkadot/account/mnemonic.js: -------------------------------------------------------------------------------- 1 | const { stringToU8a, u8aToHex } = require('@polkadot/util'); 2 | const { cryptoWaitReady, mnemonicGenerate, mnemonicToMiniSecret, mnemonicValidate, naclKeypairFromSeed } = require('@polkadot/util-crypto'); 3 | const { Keyring } = require('@polkadot/keyring'); 4 | 5 | async function main () { 6 | await cryptoWaitReady(); 7 | const mnemonicAlice = mnemonicGenerate(); 8 | 9 | console.log(`Generated mnemonic: ${mnemonicAlice}`); 10 | 11 | // Validate the mnemic string that was generated 12 | const isValidMnemonic = mnemonicValidate(mnemonicAlice); 13 | 14 | console.log(`isValidMnemonic: ${isValidMnemonic}`); 15 | 16 | // Create valid Substrate-compatible seed from mnemonic 17 | const seedAlice = mnemonicToMiniSecret(mnemonicAlice); 18 | 19 | // Generate new public/secret keypair for Alice from the supplied seed 20 | const { publicKey, secretKey } = naclKeypairFromSeed(seedAlice); 21 | } 22 | 23 | main().then().catch(console.error); 24 | -------------------------------------------------------------------------------- /examples/cosmos/account/address.js: -------------------------------------------------------------------------------- 1 | const { toBase64, toHex } = require('@cosmjs/encoding'); 2 | const { Secp256k1HdWallet, makeCosmoshubPath, pubkeyType, pubkeyToAddress } = require('@cosmjs/amino'); 3 | 4 | async function main() { 5 | const mnemonic = 'spice review cycle among deal estate main sport fold source face avocado'; 6 | const wallet = await Secp256k1HdWallet.fromMnemonic(mnemonic, { 7 | hdPaths: [makeCosmoshubPath(0)], 8 | }); 9 | 10 | console.log('wallet ', wallet.mnemonic); 11 | const [firstAccount] = await wallet.getAccounts(); 12 | const pub = firstAccount.pubkey; 13 | console.log('pub', toBase64(pub)); 14 | console.log('pub hex', toHex(pub)); 15 | 16 | const pubkey = { 17 | type: pubkeyType.secp256k1, 18 | value: toBase64(pub), 19 | }; 20 | const address = pubkeyToAddress(pubkey, 'cosmos'); 21 | console.log('address', address); 22 | console.log(firstAccount); 23 | console.log(firstAccount.address); 24 | } 25 | 26 | main().catch(console.error); 27 | -------------------------------------------------------------------------------- /examples/ethereum/blockchain/files/genesis.json: -------------------------------------------------------------------------------- 1 | { 2 | "config": { 3 | "chainId": 666, 4 | "homesteadBlock": 0, 5 | "eip150Block": 0, 6 | "eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000", 7 | "eip155Block": 0, 8 | "eip158Block": 0, 9 | "byzantiumBlock": 0, 10 | "constantinopleBlock": 0, 11 | "petersburgBlock": 0, 12 | "istanbulBlock": 0, 13 | "berlinBlock": 0, 14 | "londonBlock": 0, 15 | "ethash": {} 16 | }, 17 | "alloc": { 18 | "0x0d5A689D6a973E945cbBfab37202A1788E5588E7": { 19 | "balance": "1000000000000000000000000000" 20 | } 21 | }, 22 | "coinbase": "0x0000000000000000000000000000000000000000", 23 | "difficulty": "1", 24 | "extraData": "", 25 | "gasLimit": "0x2fefd8", 26 | "nonce": "0x0000000000000042", 27 | "mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000", 28 | "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", 29 | "timestamp": "0x00" 30 | } -------------------------------------------------------------------------------- /examples/polkadot/utils.js: -------------------------------------------------------------------------------- 1 | // Required imports 2 | const cloverTypes = require('@clover-network/node-types'); 3 | const { ApiPromise, WsProvider } = require('@polkadot/api'); 4 | 5 | async function api() { 6 | // Initialise the provider to connect to the local node 7 | const provider = new WsProvider('wss://api.clover.finance'); 8 | 9 | // Create the API and wait until ready 10 | const api = await ApiPromise.create({ provider, types: cloverTypes }); 11 | 12 | // Retrieve the chain & node information information via rpc calls 13 | const [chain, nodeName, nodeVersion] = await Promise.all([api.rpc.system.chain(), api.rpc.system.name(), api.rpc.system.version()]); 14 | 15 | console.log(`You are connected to chain ${chain} using ${nodeName} v${nodeVersion}`); 16 | return api; 17 | } 18 | 19 | exports.api = api; 20 | 21 | const sleep = async (ns) => { 22 | return new Promise((resolve) => { 23 | setTimeout(() => { 24 | resolve(); 25 | }, ns); 26 | }); 27 | }; 28 | 29 | exports.sleep = sleep; 30 | -------------------------------------------------------------------------------- /website/sidebars.ts: -------------------------------------------------------------------------------- 1 | import type { SidebarsConfig } from '@docusaurus/plugin-content-docs'; 2 | 3 | // This runs in Node.js - Don't use client-side code here (browser APIs, JSX...) 4 | 5 | /** 6 | * Creating a sidebar enables you to: 7 | - create an ordered group of docs 8 | - render a sidebar for each doc of that group 9 | - provide next/previous navigation 10 | 11 | The sidebars can be generated from the filesystem, or explicitly defined here. 12 | 13 | Create as many sidebars as you want. 14 | */ 15 | const sidebars: SidebarsConfig = { 16 | // By default, Docusaurus generates a sidebar from the docs folder structure 17 | tutorialSidebar: [ 18 | { type: 'autogenerated', dirName: '.' }, 19 | ], 20 | 21 | // But you can create a sidebar manually 22 | /* 23 | tutorialSidebar: [ 24 | 'intro', 25 | 'hello', 26 | { 27 | type: 'category', 28 | label: 'Tutorial', 29 | items: ['tutorial-basics/create-a-document'], 30 | }, 31 | ], 32 | */ 33 | }; 34 | 35 | export default sidebars; 36 | -------------------------------------------------------------------------------- /examples/bitcoin/address/multisig.ts: -------------------------------------------------------------------------------- 1 | import bitgoV1 from '@bitgo/utxo-lib'; 2 | import { payments } from 'bitcoinjs-lib'; 3 | 4 | const pubKeys = [ 5 | '02f4147da97162a214dbe25828ee4c4acc4dc721cd0c15b2761b43ed0292ed82b5', // 2 -3 6 | '0377155e520059d3b85c6afc5c617b7eb519afadd0360f1ef03aff3f7e3f5438dd', 7 | '02f44bce3eecd274e7aa24ec975388d12905dfc670a99b16e1d968e6ab5f69b266', 8 | ].map(function (hex) { 9 | return Buffer.from(hex, 'hex'); 10 | }); 11 | 12 | const threshold = 2; 13 | const network = bitgoV1.networks.testnet 14 | 15 | var redeemScript = bitgoV1.script.multisig.output.encode(threshold, pubKeys); // 2 of 3 16 | var scriptPubKey = bitgoV1.script.scriptHash.output.encode(bitgoV1.crypto.hash160(redeemScript)); 17 | var address = bitgoV1.address.fromOutputScript(scriptPubKey, network); 18 | console.log('bitgo address : ', address); 19 | 20 | // 21 | var { address } = payments.p2sh({ 22 | redeem: payments.p2ms({ m: threshold, pubkeys: pubKeys, network }), 23 | network, 24 | }); 25 | 26 | console.log('bitcoin address: ', address); 27 | -------------------------------------------------------------------------------- /website/static/icons/dot.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /examples/bitcoin/address/address.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, test, expect } from 'vitest'; 2 | import bitcoin from 'bitcoinjs-lib'; 3 | 4 | import { toBase58Address, toBech32Address } from './address'; 5 | 6 | describe('Bitcoin address', () => { 7 | test('p2pk', () => { 8 | const pub = '02d0de0aaeaefad02b8bdc8a01a1b8b11c696bd3d66a2c5f10780d95b7df42645c'; 9 | const pubkey = Buffer.from(pub, 'hex'); 10 | 11 | const { address: p2pk_address } = bitcoin.payments.p2pkh({ pubkey }); 12 | const address = toBase58Address(pubkey); 13 | 14 | expect(address).toEqual(p2pk_address); 15 | expect(address).toEqual('1LoVGDgRs9hTfTNJNuXKSpywcbdvwRXpmK'); 16 | }); 17 | 18 | test('p2wpkh', () => { 19 | const pub = '02d0de0aaeaefad02b8bdc8a01a1b8b11c696bd3d66a2c5f10780d95b7df42645c'; 20 | const pubkey = Buffer.from(pub, 'hex'); 21 | 22 | const { address: p2wpkh_address } = bitcoin.payments.p2wpkh({ pubkey }); 23 | const address = toBech32Address(pubkey); 24 | 25 | expect(address).toEqual(p2wpkh_address); 26 | expect(address).toEqual('bc1qmy63mjadtw8nhzl69ukdepwzsyvv4yex5qlmkd'); 27 | }); 28 | }); 29 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 iamnivekx 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /examples/bitcoin/script.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, test, expect } from 'vitest'; 2 | 3 | import { fromASM, toASM } from './script'; 4 | import { valid, invalid } from './__mocks__/script.json'; 5 | 6 | describe('Bitcoin script', () => { 7 | describe('fromASM/toASM', () => { 8 | test.each(valid)('encodes/decodes $asm', ({ asm }) => { 9 | const script = fromASM(asm); 10 | expect(asm).toStrictEqual(toASM(script)); 11 | }); 12 | 13 | test.each(invalid.fromASM)('invalid $script, throw " $description "', ({ script, description }) => { 14 | expect(() => { 15 | fromASM(script); 16 | }).toThrowError(new RegExp(description)); 17 | }); 18 | }); 19 | 20 | describe('compile (via fromASM)', () => { 21 | test.each(valid)('compile $asm, expect to be $script', ({ asm, script, nonstandard }) => { 22 | const scriptSig = fromASM(asm); 23 | expect(script).toStrictEqual(scriptSig.toString('hex')); 24 | if (!nonstandard) return; 25 | 26 | const scriptSigNS = fromASM(nonstandard.scriptSig); 27 | expect(script).toStrictEqual(scriptSigNS.toString('hex')); 28 | }); 29 | }); 30 | }); 31 | -------------------------------------------------------------------------------- /examples/crosschain/anyswap/abi.js: -------------------------------------------------------------------------------- 1 | const { utils } = require('ethers'); 2 | var data = 3 | '0xedbdf5e2000000000000000000000000edf0c420bc3b92b961c6ec411cc810ca81f5f21a000000000000000000000000d383acf980b70855ab0c2c4af0adaa520e39bcb3000000000000000000000000000000000000000000000000a688906bd8b000000000000000000000000000000000000000000000000000000000000000000089'; 4 | var iface = new utils.Interface([ 5 | 'function anySwapOutUnderlying(address token, address to, uint256 amount, uint256 toChainID)', 6 | 'function transfer(address recipient, uint256 amount)', 7 | ]); 8 | 9 | var input = iface.decodeFunctionData('anySwapOutUnderlying', data); 10 | console.log('input : ', input); 11 | 12 | var iface = new utils.Interface(['function anySwapOutUnderlying(anyToken,toAddress,amount,toChainID)']); 13 | var anyToken = '0xEDF0c420bc3b92B961C6eC411cc810CA81F5F21a'; 14 | var toAddress = '0xD383ACF980b70855AB0C2c4AF0Adaa520E39Bcb3'; 15 | var amount = '0xa688906bd8b00000'; 16 | var toChainID = '0x89'; 17 | var data = [anyToken, toAddress, amount, toChainID]; 18 | var input = iface.encodeFunctionData('anySwapOutUnderlying', data); 19 | console.log('input : ', input); 20 | -------------------------------------------------------------------------------- /website/docs/cosmos/intro.md: -------------------------------------------------------------------------------- 1 | # Cosmos 简介 2 | 3 | Cosmos 是一个去中心化的区块链网络,旨在解决区块链的可扩展性、可用性和互操作性挑战。 4 | 5 | ## 核心特性 6 | 7 | - **高性能**: 支持 10,000+ TPS 8 | - **低费用**: 交易费用极低 9 | - **快速确认**: 1-6 秒区块确认时间 10 | - **跨链兼容**: 支持 IBC 协议和多种代币标准 11 | - **权益证明**: 基于 PoS 的共识机制 12 | 13 | ## 技术架构 14 | 15 | Cosmos 网络由以下组件组成: 16 | 17 | - **Hub**: 中央区块链,负责连接其他区块链 18 | - **Zone**: 独立的区块链网络 19 | - **IBC**: 跨链通信协议 20 | - **Tendermint Core**: 拜占庭容错共识引擎 21 | 22 | ## 快速开始 23 | 24 | 查看 [开发指南](./guide.md) 获取完整的学习路径和开发实践。 25 | 26 | ## 网络环境 27 | 28 | | 网络 | RPC URL | 用途 | 29 | | ------ | -------------------------------------- | -------- | 30 | | 主网 | https://rpc.cosmos.network:26657 | 生产环境 | 31 | | 测试网 | https://rpc.testnet.cosmos.network:443 | 测试环境 | 32 | | 本地网 | http://localhost:26657 | 开发测试 | 33 | 34 | ## 核心概念 35 | 36 | - **账户**: 每个账户都有唯一的 Bech32 地址 37 | - **ATOM**: 原生代币,用于支付交易费用和质押 38 | - **IBC**: 跨链通信协议,实现区块链间互操作 39 | - **交易**: 包含消息的状态转换操作 40 | 41 | ## 学习资源 42 | 43 | - [Cosmos 官方文档](https://docs.cosmos.network/) 44 | - [CosmJS 库](https://github.com/cosmos/cosmjs) 45 | - [Cosmos SDK](https://github.com/cosmos/cosmos-sdk) 46 | -------------------------------------------------------------------------------- /website/docs/ethereum/intro.md: -------------------------------------------------------------------------------- 1 | # 以太坊开发指南 2 | 3 | 欢迎来到以太坊开发指南!本指南将帮助你掌握以太坊区块链开发的核心概念和实践技能。 4 | 5 | ## 什么是以太坊? 6 | 7 | 以太坊是一个去中心化的开源区块链平台,支持智能合约和去中心化应用(DApp)的开发。它使用自己的加密货币以太币(ETH)来支付交易费用和计算服务。 8 | 9 | ## 核心特性 10 | 11 | - **智能合约**: 自动执行的程序代码 12 | - **EVM**: 以太坊虚拟机,执行智能合约 13 | - **Gas机制**: 计算资源定价系统 14 | - **账户模型**: 支持EOA和智能合约账户 15 | - **PoS共识**: 权益证明机制 16 | 17 | ## 学习路径 18 | 19 | ### 1. 账户管理 20 | - [账户创建与管理](./account/account.md) 21 | - [钱包集成](./account/wallet.md) 22 | 23 | ### 2. 交易处理 24 | - [交易构建与签名](./tx/transaction.md) 25 | - [EIP-1559交易](./tx/eip1559.md) 26 | - [ABI编码解码](./tx/abi-decode.md) 27 | - [ERC20代币操作](./tx/erc20.md) 28 | - [ERC721 NFT操作](./tx/abi-decode-erc721.md) 29 | 30 | ### 3. 多重签名 31 | - [Gnosis Safe集成](./multisig/safe/gnosis.md) 32 | - [Safe部署](./multisig/safe/deploy.md) 33 | - [Safe操作](./multisig/safe/helper.md) 34 | 35 | ### 4. 区块链交互 36 | - [节点连接](./blockchain/) 37 | - [区块数据](./blockchain/) 38 | 39 | ## 开发工具 40 | 41 | - **Hardhat**: 以太坊开发环境 42 | - **ethers.js**: 以太坊JavaScript库 43 | - **ethereumjs-tx**: 交易处理库 44 | - **Web3.js**: 以太坊JavaScript API 45 | 46 | ## 网络环境 47 | 48 | - **主网**: 生产环境 49 | - **Goerli**: 测试网络 50 | - **Sepolia**: 测试网络 51 | - **本地网络**: 开发测试 52 | 53 | 开始你的以太坊开发之旅吧! 54 | -------------------------------------------------------------------------------- /examples/polkadot/old/old.js: -------------------------------------------------------------------------------- 1 | const { blake2b } = require('blakejs'); 2 | const pbkdf2 = require('pbkdf2'); 3 | const bip39 = require('bip39'); 4 | const bip32 = require('bip32'); 5 | const { Keyring } = require('@polkadot/keyring'); 6 | const { hexToU8a, u8aToHex } = require('@polkadot/util'); 7 | 8 | const { cryptoWaitReady } = require('@polkadot/util-crypto'); 9 | cryptoWaitReady().then(() => { 10 | var words = []; 11 | for (var i = 0; i < 100; i++) { 12 | const PHRASE = bip39.generateMnemonic(); //'pledge suit pyramid apple satisfy same sponsor search involve hello crystal grief'; 13 | const keyring = new Keyring({ type: 'sr25519', ss58Format: 0 }); 14 | const newPair = keyring.addFromUri(PHRASE + '//polkadot'); 15 | 16 | console.log(newPair.address.length); 17 | words.push(newPair.address.slice(0, 1)); 18 | } 19 | console.log(new Set(words)); 20 | // const sig = newPair.sign(hexToU8a('0x070000b0e2c869624ed67d80646362282107db9c264cfc91e9bac6427d433a7609d22e0f0000c16ff2862305006c001000000001000000dd97e5ad3f0015f2dc45c9467b0fd36a2b7f4b9a7bc65e8111d49d6cf19c8927f5db90b80b204e95b4b919ed067a44acc67f1783920ee46796cc4916830cb2a2'), { withType: true }) 21 | // console.log(u8aToHex(sig)) 22 | }); 23 | -------------------------------------------------------------------------------- /examples/bitcoin/address/legacy.ts: -------------------------------------------------------------------------------- 1 | import { payments, networks } from 'bitcoinjs-lib'; 2 | 3 | 4 | export function p2pkh_address(pubkey, network) { 5 | const { address } = payments.p2pkh({ pubkey, network }); 6 | return address; 7 | } 8 | 9 | export function p2wpkh_address(pubkey, network) { 10 | const { address } = payments.p2wpkh({ pubkey, network }); 11 | return address; 12 | } 13 | 14 | export function p2sh_p2wpkh_address(pubkey, network) { 15 | const p2sh = payments.p2sh({ 16 | redeem: payments.p2wpkh({ 17 | pubkey, 18 | network 19 | }), 20 | network 21 | }); 22 | return p2sh.address; 23 | } 24 | 25 | // https://bitcointools.site/tool/pubkey-to-address 26 | function main() { 27 | const network = networks.bitcoin; 28 | var pubKey = '031b98c9f3bee12048d0ea57db25372db8da504b65b2adf023123c3cc464c6f283'; 29 | const pubkey = Buffer.from(pubKey, 'hex'); 30 | 31 | var p2pkhAddr = p2pkh_address(pubkey, network); 32 | console.log('p2pkh Address: ', p2pkhAddr); 33 | 34 | var p2wpkhAddr = p2wpkh_address(pubkey, network); 35 | console.log('p2wpkh Address: ', p2wpkhAddr); 36 | 37 | var p2sh_p2wpkhAddr = p2sh_p2wpkh_address(pubkey, network); 38 | console.log('p2sh_p2wpkh Address: ', p2sh_p2wpkhAddr); 39 | 40 | } 41 | 42 | // main(); 43 | -------------------------------------------------------------------------------- /examples/ethereum/blockchain/attack/rpc/eth.js: -------------------------------------------------------------------------------- 1 | const { request } = require('./request'); 2 | 3 | // https://geth.ethereum.org/docs/rpc/ns-eth 4 | async function eth_mining(uri) { 5 | return request(uri, 'eth_mining'); 6 | } 7 | 8 | async function eth_syncing(uri) { 9 | return request(uri, 'eth_syncing'); 10 | } 11 | 12 | async function eth_coinbase(uri) { 13 | return request(uri, 'eth_coinbase'); 14 | } 15 | 16 | async function eth_getTransactionCount(uri, address) { 17 | return request(uri, 'eth_getTransactionCount', [address, 'latest']); 18 | } 19 | 20 | async function eth_getTransactionByHash(uri, hash) { 21 | return request(uri, 'eth_getTransactionByHash', [hash]); 22 | } 23 | 24 | async function eth_signTransaction(uri, tx) { 25 | return request(uri, 'eth_signTransaction', [tx]); 26 | } 27 | 28 | async function eth_sendRawTransaction(uri, raw) { 29 | return request(uri, 'eth_sendRawTransaction', [raw]); 30 | } 31 | 32 | exports.eth_mining = eth_mining; 33 | exports.eth_syncing = eth_syncing; 34 | exports.eth_coinbase = eth_coinbase; 35 | exports.eth_getTransactionCount = eth_getTransactionCount; 36 | exports.eth_getTransactionByHash = eth_getTransactionByHash; 37 | exports.eth_signTransaction = eth_signTransaction; 38 | exports.eth_sendRawTransaction = eth_sendRawTransaction; 39 | -------------------------------------------------------------------------------- /examples/bitcoin/tx/rbf.js: -------------------------------------------------------------------------------- 1 | require('dotenv').config(); 2 | const { PrivateKey, Networks, Transaction } = require('bitcore-lib'); 3 | 4 | var secret = process.env.ECDSA_SECRET; 5 | const privkey = new PrivateKey(secret, Networks.testnet); 6 | 7 | console.log('address : ', privkey.toAddress().toString()); 8 | 9 | var utxo = { 10 | txid: '5ab958a2a62d2e905128fbe0faebc998a92abf365aaa8db3f319c280dda32bc1', 11 | outputIndex: 0, 12 | address: 'n1cScasu6XVoDki38WYAJH4ZJGRAfG8XRN', 13 | script: '76a914dc6c3c43e5d2c934602095103d3cbf84ddc797f288ac', 14 | satoshis: 10000, 15 | }; 16 | 17 | const tx = new Transaction(); 18 | tx.from(utxo); 19 | tx.to('mnv5WqA2nw1L5SHepFFVNYZMeHUC9WCfRU', 8000); 20 | tx.change('mnv5WqA2nw1L5SHepFFVNYZMeHUC9WCfRU'); 21 | tx.fee(300); 22 | tx.enableRBF(); 23 | tx.sign(privkey); 24 | const bl = tx.isRBF(); 25 | console.log('bl', bl); 26 | 27 | const serialized = tx.serialize(); 28 | console.log('serialized', serialized); 29 | 30 | const newTx = new Transaction(); 31 | console.log(newTx.isRBF()); 32 | 33 | newTx.from(utxo); 34 | newTx.to('n1cScasu6XVoDki38WYAJH4ZJGRAfG8XRN', 7000); 35 | newTx.change('n1cScasu6XVoDki38WYAJH4ZJGRAfG8XRN'); 36 | newTx.fee(1800); 37 | newTx.enableRBF(); 38 | newTx.sign(privkey); 39 | 40 | const newSerialized = newTx.serialize(); 41 | console.log('new serialized : ', newSerialized); 42 | -------------------------------------------------------------------------------- /examples/bitcoin/address/address.ts: -------------------------------------------------------------------------------- 1 | import { bech32 } from 'bech32'; 2 | import base58 from 'bs58'; 3 | import { sha256x2, sha256, ripemd160 } from '../utils/crypto'; 4 | 5 | export function toBech32Address(pubkey: Buffer, pubKeyHash = 0x00): string { 6 | // pubKeyHash: Witness version. 0x00 for P2WPKH 7 | const hash256 = sha256(pubkey); 8 | const hash160 = ripemd160(hash256); 9 | 10 | const words = bech32.toWords(hash160); 11 | words.unshift(pubKeyHash); 12 | return bech32.encode('bc', words); 13 | } 14 | 15 | // https://github.com/bitcoinbook/bitcoinbook/blob/develop/ch04_keys.adoc 16 | // pubKeyHash: Version byte. 0x00 for Mainnet P2PKH, 0x6f for Testnet, etc. 17 | export function toBase58Address(pubkey: Buffer, pubKeyHash = 0x00): string { 18 | const hash256 = sha256(pubkey); 19 | const hash160 = ripemd160(hash256); 20 | 21 | // version + payload 22 | const payload = Buffer.allocUnsafe(21); 23 | payload.writeUInt8(pubKeyHash, 0); 24 | hash160.copy(payload, 1); 25 | 26 | // checksum, first 4 buffer 27 | const checksum = sha256x2(payload).slice(0, 4); 28 | 29 | // Buffer.concat([payload, checksum], payload.length + 4); 30 | const buffer = Buffer.allocUnsafe(25); 31 | payload.copy(buffer); 32 | checksum.copy(buffer, 21); 33 | 34 | // version + payload + checksum(first 4 bytes) 35 | return base58.encode(buffer); 36 | }; -------------------------------------------------------------------------------- /examples/ethereum/account/account.ts: -------------------------------------------------------------------------------- 1 | import { privateToAddress, privateToPublic, isValidPrivate, publicToAddress, toChecksumAddress } from 'ethereumjs-util'; 2 | import { ec as EC } from 'elliptic'; 3 | import 'dotenv/config'; 4 | 5 | const ec = new EC('secp256k1'); 6 | const { PRIVATE_KEY } = process.env; 7 | const privateKey = Buffer.from(PRIVATE_KEY!, 'hex'); 8 | 9 | const publicKey = privateToPublic(privateKey); 10 | const address = privateToAddress(privateKey); 11 | 12 | console.log('isValidPrivate : ', isValidPrivate(privateKey)); 13 | console.log('public key : ', publicKey.toString('hex')); 14 | console.log('private to address : ', address.toString('hex')); 15 | console.log('public to address : ', publicToAddress(publicKey).toString('hex')); 16 | console.log('BIP55 address : ', toChecksumAddress(publicToAddress(publicKey, true).toString('hex'))); 17 | 18 | const pair = ec.keyFromPrivate(privateKey); 19 | const compact = pair.getPublic(true, 'hex'); 20 | const decompose = pair.getPublic(false, 'hex'); 21 | const decomposeBuf = Buffer.from(decompose, 'hex'); 22 | const addr = publicToAddress(decomposeBuf, true).toString('hex'); 23 | console.log('compact : ', compact); 24 | console.log('decompose : ', decompose); 25 | console.log('address : ', addr); 26 | console.log('bip55 address : ', toChecksumAddress(addr)); 27 | -------------------------------------------------------------------------------- /website/static/icons/sol.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 9 | 10 | 11 | 12 | 13 | 17 | 18 | -------------------------------------------------------------------------------- /examples/solana/jupiter/instruction.ts: -------------------------------------------------------------------------------- 1 | import { AddressLookupTableAccount, Connection, PublicKey, TransactionInstruction } from '@solana/web3.js'; 2 | import { Instruction } from '@jup-ag/api'; 3 | 4 | export function deserializeInstruction(instruction: Instruction) { 5 | return new TransactionInstruction({ 6 | programId: new PublicKey(instruction.programId), 7 | keys: instruction.accounts.map((key) => ({ 8 | pubkey: new PublicKey(key.pubkey), 9 | isSigner: key.isSigner, 10 | isWritable: key.isWritable, 11 | })), 12 | data: Buffer.from(instruction.data, 'base64'), 13 | }); 14 | } 15 | 16 | export async function getAddressLookupTableAccounts(connection: Connection, keys: string[]): Promise { 17 | const addressLookupTableAccountInfos = await connection.getMultipleAccountsInfo(keys.map((key) => new PublicKey(key))); 18 | return addressLookupTableAccountInfos.reduce((acc, accountInfo, index) => { 19 | const addressLookupTableAddress = keys[index]; 20 | if (accountInfo) { 21 | const addressLookupTableAccount = new AddressLookupTableAccount({ 22 | key: new PublicKey(addressLookupTableAddress), 23 | state: AddressLookupTableAccount.deserialize(accountInfo.data), 24 | }); 25 | acc.push(addressLookupTableAccount); 26 | } 27 | return acc; 28 | }, new Array()); 29 | } 30 | -------------------------------------------------------------------------------- /website/static/icons/xrp.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 14 | 15 | -------------------------------------------------------------------------------- /examples/solana/account/get-banaces.ts: -------------------------------------------------------------------------------- 1 | import 'dotenv/config'; 2 | import { clusterApiUrl, Connection, PublicKey } from '@solana/web3.js'; 3 | import { TOKEN_PROGRAM_ID, AccountLayout } from '@solana/spl-token'; 4 | 5 | var url = clusterApiUrl('devnet'); 6 | 7 | async function main() { 8 | const connection = new Connection(url, 'confirmed'); 9 | // const ownerAddress = new PublicKey('3ejod8WdzSuQCXsY7jVvm74nBZr1JrxRnC1zZnxxBVWN'); // legacy 10 | const ownerAddress = new PublicKey('4WgeY3eNtTkUnmE85AxgJM17n1m3yAexnLjz12Fio2kk'); // multisig 11 | 12 | const balance = await connection.getBalance(ownerAddress); 13 | console.log('SOL Balance'); 14 | console.log('------------------------------------------------------------'); 15 | console.log(`${ownerAddress.toString()} ${balance}`); 16 | 17 | const tokenAccounts = await connection.getTokenAccountsByOwner(ownerAddress, { 18 | programId: TOKEN_PROGRAM_ID, 19 | }); 20 | 21 | console.log('Token Balance'); 22 | console.log('------------------------------------------------------------'); 23 | tokenAccounts.value.forEach((tokenAccount) => { 24 | const accountData = AccountLayout.decode(tokenAccount.account.data); 25 | console.log(`${new PublicKey(accountData.mint)} ${accountData.amount}`); 26 | }); 27 | } 28 | 29 | main().catch(console.error); 30 | -------------------------------------------------------------------------------- /website/docs/avalanche/intro.md: -------------------------------------------------------------------------------- 1 | # Avalanche 开发指南 2 | 3 | 欢迎来到Avalanche开发指南!本指南将帮助你掌握Avalanche区块链开发的核心概念和实践技能。 4 | 5 | ## 什么是Avalanche? 6 | 7 | Avalanche是一个高性能的Layer 1区块链平台,专注于可扩展性和低费用。它使用创新的共识机制,支持高吞吐量交易处理,并提供了三链架构来满足不同的应用需求。 8 | 9 | ## 核心特性 10 | 11 | - **高性能**: 支持4,500+ TPS 12 | - **低费用**: 交易费用极低(约$0.001) 13 | - **快速确认**: 1-3秒区块确认时间 14 | - **智能合约**: 支持EVM兼容的智能合约 15 | - **跨链兼容**: 支持多链资产转移 16 | 17 | ## 学习路径 18 | 19 | ### 1. 账户管理 20 | - [地址管理](./account/address.md) - 地址生成和密钥管理 21 | - [密钥管理](./account/key-management.md) - 助记词和HD钱包 22 | 23 | ### 2. 交易操作 24 | - [资产转移](./tx/transfer.md) - AVAX代币转账 25 | - [SDK交易](./tx/sign-sdk.md) - 使用SDK交易创建、签名和提交 26 | - [离线交易](./tx/sign-external.md) - 使用离线交易处理和签名 27 | - [高级交易构建](./tx/advanced.md) - 手动构建交易 28 | - [交易编码](./tx/decode.md) - 交易序列化 29 | 30 | ## 开发工具 31 | 32 | - **AvalancheJS**: JavaScript/TypeScript SDK 33 | - **Avalanche CLI**: 命令行工具 34 | - **Avalanche Wallet**: 官方钱包 35 | - **MetaMask**: 兼容C-Chain的以太坊钱包 36 | 37 | ## 网络环境 38 | 39 | | 网络 | RPC URL | 用途 | 40 | | ------ | ----------------------------- | -------- | 41 | | 主网 | https://api.avax.network | 生产环境 | 42 | | 测试网 | https://api.avax-test.network | 测试环境 | 43 | | 本地网 | http://localhost:9650 | 开发测试 | 44 | 45 | ## 核心概念 46 | 47 | - **三链架构**: X-Chain、P-Chain、C-Chain各司其职 48 | - **AVAX**: 原生代币,用于支付交易费用和质押 49 | - **UTXO模型**: X-Chain使用UTXO模型进行资产转移 50 | - **子网**: 可扩展的网络架构,支持自定义验证者 51 | - **共识**: 创新的Avalanche共识协议 52 | 53 | 开始你的Avalanche开发之旅吧! 54 | 55 | -------------------------------------------------------------------------------- /examples/cosmos/account/multisig.js: -------------------------------------------------------------------------------- 1 | const { strict } = require('assert'); 2 | const { Bech32, fromHex, toBase64, toHex } = require('@cosmjs/encoding'); 3 | const { createMultisigThresholdPubkey, pubkeyToAddress, pubkeyToRawAddress } = require('@cosmjs/amino'); 4 | 5 | function makeMultsigAccount(pubkeys, threshold, prefix) { 6 | const multisig = createMultisigThresholdPubkey(pubkeys, threshold, true); 7 | const multisigAddress = pubkeyToAddress(multisig, prefix); 8 | console.log('multisigAddress : ', multisigAddress); 9 | 10 | const group = { 11 | type: 'tendermint/PubKeyMultisigThreshold', 12 | value: { 13 | threshold, 14 | pubkeys, 15 | }, 16 | }; 17 | 18 | var rawAddress = pubkeyToRawAddress(group); 19 | strict.equal(Bech32.encode(prefix, rawAddress), multisigAddress, 'should be equal'); 20 | } 21 | 22 | async function main() { 23 | const threshold = 2; 24 | const prefix = 'cosmos'; 25 | var pubkeys = [ 26 | '02f4147da97162a214dbe25828ee4c4acc4dc721cd0c15b2761b43ed0292ed82b5', 27 | '0377155e520059d3b85c6afc5c617b7eb519afadd0360f1ef03aff3f7e3f5438dd', 28 | '02f44bce3eecd274e7aa24ec975388d12905dfc670a99b16e1d968e6ab5f69b266', 29 | ] 30 | .map((key) => Buffer.from(key, 'hex')) 31 | .map((key) => { 32 | return { 33 | type: 'tendermint/PubKeySecp256k1', 34 | value: toBase64(key), 35 | }; 36 | }); 37 | makeMultsigAccount(pubkeys, threshold, prefix); 38 | } 39 | 40 | main().catch(console.error); 41 | -------------------------------------------------------------------------------- /website/static/icons/apt.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 15 | 16 | -------------------------------------------------------------------------------- /website/docs/bitcoin/tx/bitgo.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: BitGo 比特币交易构建 3 | description: 使用 BitGo SDK 构建和签名比特币交易 4 | --- 5 | 6 | # BitGo 比特币交易构建 7 | 8 | BitGo 是一个企业级的比特币钱包和安全平台,提供了强大的 API 来构建和签名比特币交易。本文将介绍如何使用 BitGo SDK 进行比特币交易操作。 9 | 10 | ## 环境设置 11 | 12 | 首先需要安装 BitGo SDK: 13 | 14 | ```bash 15 | npm install bitgo 16 | ``` 17 | 18 | ## 基本配置 19 | 20 | ```javascript 21 | const BitGo = require('bitgo'); 22 | 23 | // 初始化 BitGo 实例 24 | const bitgo = new BitGo({ 25 | env: 'test', // 使用测试网 26 | accessToken: 'your_access_token' 27 | }); 28 | ``` 29 | 30 | ## 交易构建示例 31 | 32 | 以下是一个完整的比特币交易构建示例: 33 | 34 | ```ts file=/examples/bitcoin/tx/btc.bitgo.v2.js 35 | ``` 36 | 37 | ## 主要功能 38 | 39 | ### 1. 钱包创建 40 | - 支持多签名钱包 41 | - 企业级安全特性 42 | - 完整的审计日志 43 | 44 | ### 2. 交易构建 45 | - 自动 UTXO 选择 46 | - 动态手续费计算 47 | - 支持批量交易 48 | 49 | ### 3. 交易签名 50 | - 硬件安全模块 (HSM) 支持 51 | - 多签名流程管理 52 | - 离线签名支持 53 | 54 | ## 安全最佳实践 55 | 56 | 1. **访问令牌管理**: 安全存储和轮换访问令牌 57 | 2. **网络选择**: 开发时使用测试网 58 | 3. **权限控制**: 最小权限原则 59 | 4. **审计日志**: 记录所有操作 60 | 61 | ## 错误处理 62 | 63 | ```javascript 64 | try { 65 | const transaction = await wallet.sendTransaction({ 66 | address: recipientAddress, 67 | amount: amountInSatoshis, 68 | walletPassphrase: walletPassphrase 69 | }); 70 | console.log('Transaction sent:', transaction.txid); 71 | } catch (error) { 72 | console.error('Transaction failed:', error.message); 73 | } 74 | ``` 75 | 76 | ## 总结 77 | 78 | BitGo 提供了企业级的比特币交易解决方案,适合需要高安全性和可扩展性的应用场景。通过合理使用其 API,可以构建安全可靠的比特币交易系统。 -------------------------------------------------------------------------------- /website/docs/bitcoin/intro.md: -------------------------------------------------------------------------------- 1 | # 比特币开发指南 2 | 3 | 欢迎来到比特币开发指南!本指南将帮助你掌握比特币区块链开发的核心概念和实践技能。 4 | 5 | ## 什么是比特币? 6 | 7 | 比特币是世界上第一个去中心化的数字货币,它使用区块链技术来记录交易并防止双重支付。比特币网络基于工作量证明(PoW)共识机制,确保网络的安全性和去中心化。 8 | 9 | ## 核心特性 10 | 11 | - **UTXO模型**: 未花费交易输出模型 12 | - **脚本系统**: 基于栈的编程语言 13 | - **地址系统**: 支持多种地址格式 14 | - **PoW共识**: 工作量证明机制 15 | - **无状态**: 不存储账户余额 16 | 17 | ## 学习路径 18 | 19 | ### 1. 地址管理 20 | - [地址生成](./address/address.md) - Base58和Bech32地址生成 21 | - [传统地址](./address/legacy.md) - P2PKH和P2SH地址 22 | - [多重签名地址](./address/multisig.md) - 多签地址创建 23 | 24 | ### 2. 脚本系统 25 | - [脚本基础](./script/script.md) - 比特币脚本编译和反编译 26 | - [脚本分类](./script/classify.md) - 标准脚本类型识别 27 | 28 | ### 3. 交易处理 29 | - [比特币交易](./tx/bitcoin.md) - 基础交易构建 30 | - [BitGo集成](./tx/bitgo.md) - 企业级钱包集成 31 | - [交易解码](./tx/decode.md) - 交易数据解析 32 | - [RBF替换](./tx/rbf.md) - 交易费用替换 33 | 34 | ### 4. 工具函数 35 | - [加密函数](./utils/crypto.md) - SHA256、RIPEMD160等 36 | 37 | ## 开发工具 38 | 39 | - **bitcoinjs-lib**: 比特币JavaScript库 40 | - **bitcoin-ops**: 操作码定义 41 | - **bech32**: Bech32编码库 42 | - **bs58**: Base58编码库 43 | 44 | ## 网络环境 45 | 46 | | 网络 | 地址前缀 | Bech32前缀 | 用途 | 47 | | -------- | -------- | ---------- | -------- | 48 | | 主网 | 1, 3 | bc1 | 生产环境 | 49 | | 测试网 | m, n, 2 | tb1 | 测试环境 | 50 | | 回归测试 | m, n, 2 | bcrt1 | 开发测试 | 51 | 52 | ## 地址格式 53 | 54 | - **Legacy (P2PKH)**: 以"1"开头的传统地址 55 | - **P2SH**: 以"3"开头的脚本哈希地址 56 | - **Native SegWit (P2WPKH)**: 以"bc1"开头的见证地址 57 | - **Taproot (P2TR)**: 以"bc1p"开头的Taproot地址 58 | 59 | 开始你的比特币开发之旅吧! 60 | -------------------------------------------------------------------------------- /examples/solana/subscribes/wsol-usdc.ts: -------------------------------------------------------------------------------- 1 | import { Connection, PublicKey } from '@solana/web3.js'; 2 | import { PoolInfoLayout, SqrtPriceMath } from '@raydium-io/raydium-sdk'; 3 | import 'dotenv/config'; 4 | // Raydium Liquidity Pool V4: WSOL-USDC 5 | const marketId = new PublicKey('8sLbNZoA1cfnvMJLPfp98ZLAnFSYCFApfJKMbiXNLwxj'); 6 | const WSOL_MINT = new PublicKey('So11111111111111111111111111111111111111112'); 7 | const USDC_MINT = new PublicKey('EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v'); 8 | 9 | function onPriceChange(conn: Connection) { 10 | conn.onAccountChange( 11 | marketId, 12 | async (accountInfo) => { 13 | try { 14 | const poolData = PoolInfoLayout.decode(accountInfo.data); 15 | const price = SqrtPriceMath.sqrtPriceX64ToPrice(poolData.sqrtPriceX64, poolData.mintDecimalsA, poolData.mintDecimalsB).toFixed(6); 16 | console.log(`WSOL/USDC:`, price); 17 | } catch (error) { 18 | console.error('Error decoding pool data:', error); 19 | } 20 | }, 21 | { 22 | commitment: 'confirmed', 23 | }, 24 | ); 25 | } 26 | 27 | function main() { 28 | // Establish new connect to mainnet - websocket client connected to mainnet will also be registered here 29 | const { SOLANA_RPC_URL, SOLANA_WS_URL } = process.env; 30 | console.log('SOLANA_RPC_URL : ', SOLANA_WS_URL); 31 | 32 | const conn = new Connection(SOLANA_RPC_URL, { 33 | commitment: 'confirmed', 34 | wsEndpoint: SOLANA_WS_URL, 35 | }); 36 | onPriceChange(conn); 37 | } 38 | 39 | main(); 40 | -------------------------------------------------------------------------------- /.github/workflows/deploy.yml: -------------------------------------------------------------------------------- 1 | name: Deploy to GitHub Pages 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | # Review gh actions docs if you want to further define triggers, paths, etc 8 | # https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#on 9 | workflow_dispatch: 10 | 11 | # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages 12 | permissions: 13 | contents: read 14 | pages: write 15 | id-token: write 16 | 17 | jobs: 18 | build: 19 | name: Build Website 20 | runs-on: ubuntu-latest 21 | steps: 22 | - name: Checkout repository 23 | uses: actions/checkout@v4 24 | 25 | - name: Setup pnpm 26 | uses: pnpm/action-setup@v4 27 | 28 | - name: Setup Node 29 | uses: actions/setup-node@v4 30 | with: 31 | node-version-file: .nvmrc 32 | cache: pnpm 33 | 34 | - name: Install dependencies 35 | run: pnpm install --frozen-lockfile --prefer-offline 36 | 37 | - name: Build website 38 | run: pnpm run build 39 | 40 | - name: Upload Build Artifact 41 | uses: actions/upload-pages-artifact@v3 42 | with: 43 | path: ./website/build 44 | 45 | deploy: 46 | runs-on: ubuntu-latest 47 | needs: build 48 | environment: 49 | name: github-pages 50 | url: ${{ steps.deployment.outputs.page_url }} 51 | steps: 52 | - name: Deploy to GitHub Pages 53 | id: deployment 54 | uses: actions/deploy-pages@v4 55 | -------------------------------------------------------------------------------- /website/src/components/ui/avatar.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | 3 | import * as React from 'react'; 4 | import * as AvatarPrimitive from '@radix-ui/react-avatar'; 5 | 6 | import { cn } from '../../lib/utils'; 7 | 8 | const Avatar = React.forwardRef, React.ComponentPropsWithoutRef>( 9 | ({ className, ...props }, ref) => ( 10 | 11 | ), 12 | ); 13 | Avatar.displayName = AvatarPrimitive.Root.displayName; 14 | 15 | const AvatarImage = React.forwardRef< 16 | React.ElementRef, 17 | React.ComponentPropsWithoutRef 18 | >(({ className, ...props }, ref) => ( 19 | 20 | )); 21 | AvatarImage.displayName = AvatarPrimitive.Image.displayName; 22 | 23 | const AvatarFallback = React.forwardRef< 24 | React.ElementRef, 25 | React.ComponentPropsWithoutRef 26 | >(({ className, ...props }, ref) => ( 27 | 32 | )); 33 | AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName; 34 | 35 | export { Avatar, AvatarImage, AvatarFallback }; 36 | -------------------------------------------------------------------------------- /examples/polkadot/multisig/fund.js: -------------------------------------------------------------------------------- 1 | const cloverTypes = require('@clover-network/node-types'); 2 | const { ApiPromise, WsProvider, Keyring } = require('@polkadot/api'); 3 | const { formatBalance } = require('@polkadot/util'); 4 | const BN = require('bn.js'); 5 | const { alice, aaron, phcc, provider } = require('../../private'); 6 | 7 | async function main() { 8 | const wsProvider = new WsProvider(provider); 9 | const api = await ApiPromise.create({ provider: wsProvider, types: cloverTypes }); 10 | 11 | // 1. Define relevant constants 12 | formatBalance.setDefaults({ 13 | unit: 'CLV', 14 | decimals: 18, 15 | }); 16 | 17 | // 2. Define relevant constants 18 | const THRESHOLD = 2; 19 | const SS58PREFIX = 42; 20 | const AMOUNT_TO_SEND = new BN('10000000000000000'); 21 | const displayAmount = formatBalance(AMOUNT_TO_SEND); 22 | 23 | // 3. Initialize accounts 24 | 25 | const addresses = [ 26 | alice.address, // addresses[0] 27 | aaron.address, // addresses[1] 28 | phcc.address, // addresses[2] 29 | ]; 30 | 31 | const MULTISIG = encodeMultiAddress(addresses, THRESHOLD, SS58PREFIX); 32 | console.log(`Multisig Address: ${MULTISIG}\n`); 33 | 34 | // 4. Send 2 CLV to multisig account 35 | const txHash = await api.tx.balances.transfer(MULTISIG, AMOUNT_TO_SEND).signAndSend(alice); 36 | console.log(`Sending ${displayAmount} from ${alice.address} to ${MULTISIG}`); 37 | console.log(`transfer tx: https://clover-testnet.subscan.io/extrinsic/${txHash}`); 38 | } 39 | 40 | main() 41 | .then() 42 | .catch(console.error) 43 | .finally(() => process.exit()); 44 | -------------------------------------------------------------------------------- /examples/polkadot/account/multi.js: -------------------------------------------------------------------------------- 1 | const { createKeyMulti, encodeAddress, sortAddresses } = require('@polkadot/util-crypto'); 2 | 3 | const SS58Prefix = 42; 4 | 5 | // Input the addresses that will make up the multisig account. 6 | const addresses = ['1nUC7afqmo7zwRFWxDjrUQu9skk6fk99pafb4SiyGSRc8z3', '1ZX2XntfLEHrBPy73DpfQp9rG7pbLyvrFjEpi7mNKQgyga5', '14b1kB7CrqzRUeMsKc26FJ73f8FCpxAX6sNieu9gfYSfJuoL']; 7 | // 5C9NCiDqwx82Ke3RCJgJUoK6ZbrVhwZkGRPnaZEBvLRN2kJW 8 | 9 | // The number of accounts that must approve. Must be greater than 0 and less than 10 | // or equal to the total number of addresses. 11 | const threshold = 2; 12 | 13 | // The address (as index in `addresses`) that will submit a transaction. 14 | const index = 0; 15 | 16 | // npx @w3f/msig-util derive --addresses 1nUC7afqmo7zwRFWxDjrUQu9skk6fk99pafb4SiyGSRc8z3,1ZX2XntfLEHrBPy73DpfQp9rG7pbLyvrFjEpi7mNKQgyga5,14b1kB7CrqzRUeMsKc26FJ73f8FCpxAX6sNieu9gfYSfJuoL --threshold 2 17 | function main() { 18 | // Address as a byte array. 19 | const multiAddress = createKeyMulti(addresses, threshold); 20 | 21 | // Convert byte array to SS58 encoding. 22 | const Ss58Address = encodeAddress(multiAddress, SS58Prefix); 23 | 24 | console.log(`\nMultisig Address: ${Ss58Address}`); 25 | 26 | // Take addresses and remove the sender. 27 | const otherSignatories = addresses.filter((who) => who !== addresses[index]); 28 | 29 | // Sort them by public key. 30 | const otherSignatoriesSorted = sortAddresses(otherSignatories, SS58Prefix); 31 | 32 | console.log(`\nOther Signatories: ${otherSignatoriesSorted}\n`); 33 | 34 | process.exit(); 35 | } 36 | 37 | main(); 38 | -------------------------------------------------------------------------------- /elliptic/curve25519.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is used to generate a public key from a secret key using the curve25519 elliptic curve. 3 | * The public key is then used to verify a signature. 4 | * libraries 5 | * : noble-curves(https://github.com/paulmillr/noble-curves) 6 | * : elliptic(https://github.com/indutny/elliptic) 7 | * : tweetnacl-js(https://github.com/dchest/tweetnacl-js) 8 | * • elliptic: A library for elliptic curve cryptography, implements curve25519 9 | * • tweetnacl-js: A library for cryptography, implements x25519-xsalsa20-poly1305 10 | */ 11 | import 'dotenv/config'; 12 | 13 | import { hexToBytes, bytesToHex } from '@noble/curves/abstract/utils'; 14 | import { ec as EC } from 'elliptic'; 15 | import nacl from 'tweetnacl'; 16 | 17 | var secret = process.env.CURVE_25519_SECRET; 18 | const ec = new EC('curve25519'); 19 | 20 | export function elliptic(): void { 21 | var key1 = ec.genKeyPair(); 22 | var key2 = ec.genKeyPair(); 23 | 24 | var shared1 = key1.derive(key2.getPublic()); 25 | var shared2 = key2.derive(key1.getPublic()); 26 | 27 | console.log('Both shared secrets are BN instances'); 28 | console.log('shared secrets: ', shared1.toString(16)); 29 | console.log('shared secrets: ', shared2.toString(16)); 30 | 31 | var keyPair = ec.keyFromPrivate(secret); 32 | console.log('Public key:', keyPair.getPublic('hex')); 33 | } 34 | 35 | export function tweetnacl() { 36 | var secretKey = hexToBytes(secret); 37 | var keyPair = nacl.box.keyPair.fromSecretKey(secretKey); 38 | console.log('Public key:', bytesToHex(keyPair.publicKey)); 39 | } 40 | 41 | function main() { 42 | elliptic(); 43 | tweetnacl(); 44 | } 45 | 46 | main(); 47 | -------------------------------------------------------------------------------- /website/docs/tron/intro.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: intro 3 | title: Tron 区块链介绍 4 | sidebar_label: 介绍 5 | --- 6 | 7 | # Tron 区块链介绍 8 | 9 | Tron 是一个去中心化的区块链平台,旨在构建全球数字内容娱乐系统。它使用权益证明(DPoS)共识机制,提供高吞吐量和低交易费用。 10 | 11 | ## 主要特性 12 | 13 | - **高吞吐量**: 支持每秒数千笔交易 14 | - **低费用**: 交易费用极低,适合小额交易 15 | - **智能合约**: 支持 Solidity 智能合约 16 | - **代币标准**: 支持 TRC10 和 TRC20 代币 17 | - **去中心化应用**: 支持 DApp 开发 18 | 19 | ## 技术架构 20 | 21 | ### 共识机制 22 | Tron 使用委托权益证明(DPoS)共识机制,由 27 个超级代表节点维护网络。 23 | 24 | ### 账户模型 25 | - 使用椭圆曲线数字签名算法(ECDSA) 26 | - 支持 secp256k1 曲线 27 | - 地址格式:Base58Check 编码 28 | 29 | ### 网络类型 30 | - **主网**: 主网环境,真实资产 31 | - **Shasta 测试网**: 官方测试网络 32 | - **Nile 测试网**: 社区测试网络 33 | 34 | ## 开发工具 35 | 36 | ### 核心库 37 | - **TronWeb**: 官方 JavaScript SDK 38 | - **TronBox**: 智能合约开发框架 39 | - **TronGrid**: 区块链数据 API 40 | 41 | ### 开发环境 42 | ```bash 43 | # 安装 TronWeb 44 | npm install tronweb 45 | 46 | # 安装 TronBox 47 | npm install -g tronbox 48 | ``` 49 | 50 | ## 快速开始 51 | 52 | ### 1. 创建 TronWeb 实例 53 | ```javascript 54 | const TronWeb = require('tronweb'); 55 | 56 | const fullNode = 'https://api.trongrid.io'; 57 | const solidityNode = 'https://api.trongrid.io'; 58 | const eventServer = 'https://api.trongrid.io'; 59 | const privateKey = 'your-private-key'; 60 | 61 | const tronWeb = new TronWeb(fullNode, solidityNode, eventServer, privateKey); 62 | ``` 63 | 64 | ### 2. 生成账户 65 | ```javascript 66 | const account = await tronWeb.createAccount(); 67 | console.log('Address:', account.address.base58); 68 | console.log('Private Key:', account.privateKey); 69 | ``` 70 | 71 | ### 3. 查询余额 72 | ```javascript 73 | const balance = await tronWeb.trx.getBalance(address); 74 | console.log('Balance:', balance); 75 | ``` 76 | -------------------------------------------------------------------------------- /website/docs/solana/intro.md: -------------------------------------------------------------------------------- 1 | # Solana 开发指南 2 | 3 | 欢迎来到Solana开发指南!本指南将帮助你掌握Solana区块链开发的核心概念和实践技能。 4 | 5 | ## 什么是Solana? 6 | 7 | Solana是一个高性能的Layer 1区块链平台,专注于可扩展性和低费用。它使用创新的共识机制组合,包括历史证明(PoH)和工作量证明(PoW),支持高吞吐量交易处理。 8 | 9 | ## 核心特性 10 | 11 | - **高性能**: 支持65,000+ TPS 12 | - **低费用**: 交易费用极低(约$0.00025) 13 | - **快速确认**: 400ms区块确认时间 14 | - **智能合约**: 支持Rust、C、C++等语言 15 | - **跨链兼容**: 支持SPL代币标准 16 | 17 | ## 学习路径 18 | 19 | ### 1. 账户管理 20 | - [账户创建](./account/account.md) - 账户生成和密钥管理 21 | - [余额查询](./account/balance.md) - 余额查询 22 | 23 | ### 2. SOL/SPL-TOKEN 24 | - [SPL代币](./token/spl-token.md) - SPL代币操作 25 | - [SOL转账](./token/send-sol.md) - 原生SOL转账 26 | 27 | ### 3. DeFi集成 28 | - [Jupiter聚合器](./defi/jupiter.md) - 去中心化交易聚合 29 | - [Raydium集成](./defi/raydium.md) - AMM流动性池操作 30 | 31 | ### 4. 多重签名 32 | - [Squads V3](./multisig/squads-v3.md) - 传统多重签名钱包管理 33 | - [Squads V4](./multisig/squads-v4.md) - 模块化多重签名钱包管理 34 | 35 | ### 5. 订阅和监控 36 | - [事件订阅](./subscribes/subscribes.md) - 区块链事件监听 37 | - [价格监控](./subscribes/price.md) - 代币价格实时监控 38 | 39 | ## 开发工具 40 | 41 | - **Solana CLI**: 命令行工具 42 | - **@solana/web3.js**: JavaScript/TypeScript SDK 43 | - **@solana/spl-token**: SPL代币库 44 | - **Anchor**: Rust智能合约框架 45 | - **Phantom**: 钱包扩展 46 | 47 | ## 网络环境 48 | 49 | | 网络 | RPC URL | 用途 | 50 | | ------ | ----------------------------------- | -------- | 51 | | 主网 | https://api.mainnet-beta.solana.com | 生产环境 | 52 | | 测试网 | https://api.testnet.solana.com | 测试环境 | 53 | | 开发网 | https://api.devnet.solana.com | 开发测试 | 54 | 55 | ## 核心概念 56 | 57 | - **账户**: 每个账户都有唯一的公钥地址 58 | - **SOL**: 原生代币,用于支付交易费用和质押 59 | - **SPL**: Solana程序库,定义代币标准 60 | - **交易**: 包含指令的状态转换操作 61 | - **程序**: 可执行的智能合约代码 62 | 63 | 开始你的Solana开发之旅吧! 64 | -------------------------------------------------------------------------------- /website/docs/crosschain/anyswap/FAQ.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: AnySwap 常见问题 3 | description: 关于使用 AnySwap 进行跨链转移的常见问题 4 | --- 5 | 6 | # AnySwap 常见问题 7 | 8 | ## 一般问题 9 | 10 | ### 什么是 AnySwap? 11 | 12 | AnySwap 是一个去中心化的跨链桥接协议,允许用户在不同区块链网络之间转移数字资产。它支持包括以太坊、BSC、Polygon 等在内的 20 多条链。 13 | 14 | ### AnySwap 是如何工作的? 15 | 16 | AnySwap 通过在源链上锁定资产并在目标链上铸造等值代币来工作。该协议使用验证者网络来保护这些跨链交易。 17 | 18 | ### AnySwap 安全吗? 19 | 20 | AnySwap 已经过审计,在 DeFi 生态系统中被广泛使用。但是,像所有跨链桥接一样,存在固有风险。始终进行自己的研究,从小额开始。 21 | 22 | ## 技术问题 23 | 24 | ### 我可以桥接哪些代币? 25 | 26 | AnySwap 支持大多数 ERC-20、BEP-20 和其他标准代币。可用的具体代币取决于你桥接的链。 27 | 28 | ### 转移需要多长时间? 29 | 30 | 转移时间因链而异: 31 | - 快速链(BSC、Polygon):5-15 分钟 32 | - 以太坊:10-30 分钟 33 | - 其他链:15-60 分钟 34 | 35 | ### 费用是多少? 36 | 37 | 费用包括: 38 | - 源链上的 gas 费用 39 | - 目标链上的 gas 费用 40 | - 桥接费用(通常为 0.1-0.3%) 41 | - 网络费用(因链而异) 42 | 43 | ### 如果转移失败会怎样? 44 | 45 | 如果转移失败,你的资产将保留在源链上。你可能需要支付 gas 费用来重试交易。 46 | 47 | ## 故障排除 48 | 49 | ### 我的交易卡住了 50 | 51 | 1. 检查两条链上的交易状态 52 | 2. 验证你有足够的 gas 费用 53 | 3. 检查目标链是否遇到问题 54 | 4. 如有需要,联系 AnySwap 支持 55 | 56 | ### 我收到的数量不对 57 | 58 | 1. 检查转移时的汇率 59 | 2. 验证最小转移数量 60 | 3. 检查是否有滑点或费用 61 | 4. 联系支持并提供交易详情 62 | 63 | ### 如何检查转移状态? 64 | 65 | 1. 使用 AnySwap 浏览器 66 | 2. 检查源链和目标链浏览器 67 | 3. 使用 AnySwap API 68 | 4. 监控你的钱包余额 69 | 70 | ## 最佳实践 71 | 72 | ### 桥接前 73 | 74 | - 验证每个网络的路由器地址 75 | - 检查最小转移数量 76 | - 确保两条链都有足够的 gas 费用 77 | - 先用小额测试 78 | 79 | ### 桥接期间 80 | 81 | - 不要关闭浏览器或钱包 82 | - 跟踪交易哈希 83 | - 监控两条链的确认状态 84 | 85 | ### 桥接后 86 | 87 | - 验证收到的数量 88 | - 检查是否有待处理的交易 89 | - 保存交易详情以供参考 90 | 91 | ## 支持 92 | 93 | ### 在哪里可以获得帮助? 94 | 95 | - [AnySwap 文档](https://docs.anyswap.exchange/) 96 | - [AnySwap Discord](https://discord.gg/anyswap) 97 | - [AnySwap Telegram](https://t.me/anyswap) 98 | - [GitHub Issues](https://github.com/anyswap) 99 | -------------------------------------------------------------------------------- /examples/stellar/account/index.js: -------------------------------------------------------------------------------- 1 | const StellarSdk = require('stellar-sdk'); 2 | 3 | const { eddsa: EdDSA } = require('elliptic'); 4 | const ec = new EdDSA('ed25519'); 5 | const server = new StellarSdk.Server('https://horizon-testnet.stellar.org'); 6 | 7 | async function main() { 8 | const pair = StellarSdk.Keypair.random(); 9 | 10 | // 11 | const pub = Buffer.from('01ac1a962dbf53b43fbd5a2b30a5016ac93051a62b81b5721c7842bc32fc47b3', 'hex'); 12 | const pair1 = new StellarSdk.Keypair({ type: 'ed25519', publicKey: pub }); 13 | console.log('pair pub key : ', pair1.publicKey()); 14 | const publicKey = pair.publicKey(); 15 | const rawPublicKey = pair.rawPublicKey().toString('hex'); 16 | const xdrAccountId = pair.xdrAccountId(); 17 | const type = pair.xdrAccountId().switch(); 18 | const xdr = pair.xdrAccountId().toXDR('base64'); 19 | 20 | const isValid = StellarSdk.StrKey.isValidEd25519PublicKey(); 21 | // const 22 | const encodeEd25519PublicKey = StellarSdk.StrKey.encodeEd25519PublicKey(pub); 23 | console.log('isValid', isValid); 24 | console.log('encodeEd25519PublicKey', encodeEd25519PublicKey); 25 | // const type = pair.xdrAccountId().switch(); 26 | 27 | // console.log('secret', secret); 28 | console.log('publicKey : ', publicKey); 29 | console.log('rawPublicKey : ', rawPublicKey); 30 | // console.log('xdrAccountId : ', xdrAccountId); 31 | console.log('switch : ', type); 32 | console.log('xdr : ', xdr); 33 | return; 34 | const account = await server.loadAccount(publicKey); 35 | // console.log('Balances for account: ' + pub); 36 | account.balances.forEach(function (balance) { 37 | console.log('Type:', balance.asset_type, ', Balance:', balance.balance); 38 | }); 39 | } 40 | 41 | main().catch(console.error); 42 | -------------------------------------------------------------------------------- /examples/tron/tx/decode.js: -------------------------------------------------------------------------------- 1 | var ethers = require('ethers'); 2 | 3 | const AbiCoder = ethers.utils.AbiCoder; 4 | const ADDRESS_PREFIX_REGEX = /^(41)/; 5 | const ADDRESS_PREFIX = '41'; 6 | 7 | //types:Parameter type list, if the function has multiple return values, the order of the types in the list should conform to the defined order 8 | //output: Data before decoding 9 | //ignoreMethodHash:Decode the function return value, fill falseMethodHash with false, if decode the data field in the gettransactionbyid result, fill ignoreMethodHash with true 10 | 11 | async function decodeParams(types, output, ignoreMethodHash) { 12 | if (!output || typeof output === 'boolean') { 13 | ignoreMethodHash = output; 14 | output = types; 15 | } 16 | 17 | if (ignoreMethodHash && output.replace(/^0x/, '').length % 64 === 8) output = '0x' + output.replace(/^0x/, '').substring(8); 18 | 19 | const abiCoder = new AbiCoder(); 20 | 21 | // if (output.replace(/^0x/, '').length % 64) throw new Error('The encoded string is not valid. Its length must be a multiple of 64.'); 22 | return abiCoder.decode(types, output).reduce((obj, arg, index) => { 23 | if (types[index] == 'address') arg = ADDRESS_PREFIX + arg.substr(2).toLowerCase(); 24 | obj.push(arg); 25 | return obj; 26 | }, []); 27 | } 28 | 29 | async function main() { 30 | let data = '0a02d7402208ade449bde770234e4098f998f1b22f5204706863635a65080112610a2d747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e5472616e73666572436f6e747261637412300a15410e84b2c819e29881f8cee83c8b809a3b64669d24121541d8826d3b6e82bafd3085dc71a72b30253a99722f180a70f8ab95f1b22f'; 31 | 32 | result = await decodeParams(['address', 'uint256'], data, true); 33 | console.log(result); 34 | } 35 | 36 | main().catch(console.error); 37 | -------------------------------------------------------------------------------- /examples/solana/spl-token/account.ts: -------------------------------------------------------------------------------- 1 | import 'dotenv/config'; 2 | import bs58 from 'bs58'; 3 | import { clusterApiUrl, Connection, Keypair } from '@solana/web3.js'; 4 | import { createMultisig } from '@solana/spl-token'; 5 | 6 | var url = clusterApiUrl('devnet'); 7 | console.log('url : ', url); 8 | var connection = new Connection(url, 'confirmed'); 9 | 10 | async function main() { 11 | var secretKey = process.env.SOL_SECRET_KEY; 12 | var aliceKey = process.env.SOL_ALICE_KEY; 13 | var bobKey = process.env.SOL_BOB_KEY; 14 | var carolKey = process.env.SOL_CAROL_KEY; 15 | 16 | const payer = Keypair.fromSecretKey(bs58.decode(secretKey)); 17 | 18 | // 2-3 multisig 19 | const alice = Keypair.fromSecretKey(bs58.decode(aliceKey)); 20 | const bob = Keypair.fromSecretKey(bs58.decode(bobKey)); 21 | const carol = Keypair.fromSecretKey(bs58.decode(carolKey)); 22 | 23 | console.log('payer : ', payer.publicKey.toBase58()); 24 | console.log('alice : ', alice.publicKey.toBase58()); 25 | console.log('bob : ', bob.publicKey.toBase58()); 26 | console.log('carol : ', carol.publicKey.toBase58()); 27 | 28 | // create multisig account, at least 2 signers 29 | const multisigKey = await createMultisig( 30 | connection, 31 | payer, 32 | [alice.publicKey, bob.publicKey, carol.publicKey], // 33 | 2, 34 | ); 35 | const multisigAddress = multisigKey.toBase58(); 36 | 37 | console.log(`Created 2/3 multisig ${multisigAddress}`); 38 | console.log(`https://explorer.solana.com/address/${multisigAddress}?cluster=devnet`); 39 | 40 | // GQDnfiPbgbC5CJ3VjZP6NFhgiESG6cqR1DZe94Wuvi9H 41 | // https://explorer.solana.com/address/GQDnfiPbgbC5CJ3VjZP6NFhgiESG6cqR1DZe94Wuvi9H?cluster=devnet 42 | return; 43 | } 44 | 45 | main().catch(console.error); 46 | -------------------------------------------------------------------------------- /examples/avalanche/account.js: -------------------------------------------------------------------------------- 1 | const { Mnemonic } = require('avalanche'); 2 | const mnemonic = Mnemonic.getInstance(); 3 | const strength = 256; 4 | const wordlist = mnemonic.getWordlists('english'); 5 | var m = mnemonic.generateMnemonic(strength); 6 | // juice garden awake mask festival blanket benefit pelican mimic stuff clay edge ten view easy hungry buffalo become exclude salon bamboo inflict fault tiny 7 | // console.log(m); 8 | 9 | var m = 10 | 'juice garden awake mask festival blanket benefit pelican mimic stuff clay edge ten view easy hungry buffalo become exclude salon bamboo inflict fault tiny'; 11 | const { HDNode, Avalanche } = require('avalanche'); 12 | const seed = mnemonic.mnemonicToSeedSync(m); 13 | const hdnode = new HDNode(seed); 14 | 15 | const ip = 'api.avax-test.network'; 16 | const port = 9644350; 17 | const protocol = 'https'; 18 | const networkID = 5; 19 | const avalanche = new Avalanche(ip, port, protocol, networkID); 20 | 21 | const xchain = avalanche.XChain(); //returns a reference to the X-Chain used by AvalancheJS 22 | const keychain = xchain.keyChain(); 23 | 24 | for (let i = 0; i <= 0; i++) { 25 | // Deriving the _i_th external BIP44 X-Chain address 26 | const child = hdnode.derive(`m/44'/9000'/0'/0/${i}`); 27 | console.log('child.privateKeyCB58', child.privateKeyCB58); 28 | console.log('child.privateKey', child.privateKey.toString('hex')); 29 | console.log('child.publicKey', child.publicKey.toString('hex')); 30 | keychain.importKey(child.privateKeyCB58); 31 | } 32 | 33 | const xAddressStrings = xchain.keyChain().getAddressStrings(); 34 | console.log(xAddressStrings); 35 | // [ 36 | // 'X-fuji1cfvdpdqyzpp8pq0g6trmjsrn9pt8nutsfm7a40', 37 | // 'X-fuji1y75dj6qygj7frw2xtcfn724qfty4aadnmeth6y', 38 | // 'X-fuji1p6n0vyjqgmp06f7pr405q2flqu9v93j383ncam' 39 | // ] 40 | -------------------------------------------------------------------------------- /examples/ethereum/tx/decode.js: -------------------------------------------------------------------------------- 1 | const { TransactionFactory } = require('@ethereumjs/tx'); 2 | const { addHexPrefix, toBuffer } = require('ethereumjs-util'); 3 | const { default: Common, Chain, Hardfork } = require('@ethereumjs/common'); 4 | 5 | const common = new Common({ chain: Chain.Goerli, hardfork: Hardfork.London }); 6 | 7 | const serialized = '02f9028f0501833c339783426967830197cd949d055026eb8d83ef561d5d8084f2dd02e7ad2c1780b902246a761202000000000000000000000000a7a9e710f9a3b4184d4f8b7d379cec262f2382c200000000000000000000000000000000000000000000000000006d23ad5f800000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b26d000000000000000000000000000000000000000000000000000000000000d6a4000000000000000000000000000000000000000000000000000000003b9d966c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010f564f105ba1dec06087fe09329959dbd6b862d0000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000825d3d400efee000778fd26ff1a9d1a54a05e29033f8fa26ece47c5033355201b5218a6ce14d4809967ac063e0f50160cfccb7d7d06880b2de532dba60e0415f901b2bc8c0aba0e4cc0918d6ed549d63573319fb019b16d8fac000b6b41131fdf37a4817bf4d82bd285da15d229e3c9ac10b121de25344b828c0b37d3019329b4ec51b000000000000000000000000000000000000000000000000000000000000c080a00c044096a960503f62cd4e2719d50bcf551237513d9ac49b7533670da27a1f3aa034318f8c66e16c695096f0ac2bae1502990e373a2f2cc37871c913731c381785'; 8 | const typed = TransactionFactory.fromSerializedData(toBuffer(addHexPrefix(serialized)), { common }); 9 | const jsonTx = typed.toJSON(); 10 | console.log(jsonTx); 11 | -------------------------------------------------------------------------------- /examples/bitcoin/tx/bitcoin.js: -------------------------------------------------------------------------------- 1 | require('dotenv').config(); 2 | const { ECPair, Psbt, networks, payments } = require('bitcoinjs-lib'); 3 | const network = networks.testnet; 4 | 5 | var secret = process.env.ECDSA_SECRET; 6 | 7 | const signer = ECPair.fromPrivateKey(Buffer.from(secret, 'hex'), network); 8 | const pubkey = signer.publicKey; 9 | 10 | const { address } = payments.p2pkh({ pubkey, network }); 11 | console.log('pubkey : ', pubkey.toString('hex')); 12 | console.log('address : ', address); 13 | 14 | // https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/transactions.spec.ts 15 | function createPsbtTx() { 16 | const psbt = new Psbt({ network }); 17 | psbt.setVersion(2); // These are defaults. This line is not needed. 18 | psbt.setLocktime(0) 19 | 20 | psbt.addInput({ 21 | hash: '3b948165cfb707320ccdc9582b5acc7cdad213bc81b7edb37546e1334d802b38', 22 | index: 0, 23 | sequence: 0xffffffff, // These are defaults. This line is not needed. 24 | // tx raw data 25 | nonWitnessUtxo: Buffer.from('0100000001b2533a7e2329b92b576309969ef39e987f1ce62d76d1a3e714e1f73b830f7404010000006b483045022100e950df33415553a6cdd9665d4d6d3f03568ad0e2feb429efe19f4fc78da66714022059e3ffdf36d300a9352b971f8c48180ec0cef2325f61948488480430bc24d1ed012102ff26c5980685ae12d25312a8df8224c951a68272013425ffa60327d7d4b54231ffffffff0210270000000000001976a914dc6c3c43e5d2c934602095103d3cbf84ddc797f288ace71a0100000000001976a914dc6c3c43e5d2c934602095103d3cbf84ddc797f288ac00000000', 'hex') 26 | }); 27 | 28 | psbt.addOutput({ 29 | address: 'n1cScasu6XVoDki38WYAJH4ZJGRAfG8XRN', 30 | value: 9800 31 | }); 32 | 33 | psbt.signInput(0, signer); 34 | 35 | psbt.finalizeAllInputs(); 36 | 37 | const serialized = psbt.extractTransaction().toHex(); 38 | console.log('serialized : ', serialized); 39 | 40 | } 41 | 42 | createPsbtTx(); -------------------------------------------------------------------------------- /examples/polkadot/sign.js: -------------------------------------------------------------------------------- 1 | const bip39 = require('bip39'); 2 | const { ec: EC } = require('elliptic'); 3 | const { Keyring } = require('@polkadot/keyring'); 4 | const { hexToU8a, u8aToHex, bnToU8a, u8aConcat } = require('@polkadot/util'); 5 | const { cryptoWaitReady, secp256k1Sign, blake2AsU8a, EXPAND_OPT } = require('@polkadot/util-crypto'); 6 | 7 | cryptoWaitReady().then(() => { 8 | const ss58Format = 42; 9 | const keyring = new Keyring({ ss58Format, type: 'ecdsa' }); 10 | const pair = keyring.addFromUri(PHRASE + '//polkadot'); 11 | 12 | const message = 13 | '0x0700000e5797b5449c8a6526fb5fcf1a159fbc2bbdd197405aed62a9db35d1b9946e7aa10f00f0001100000001000000dd97e5ad3f0015f2dc45c9467b0fd36a2b7f4b9a7bc65e8111d49d6cf19c8927dd97e5ad3f0015f2dc45c9467b0fd36a2b7f4b9a7bc65e8111d49d6cf19c8927'; 14 | // console.log('address : ', pair.address); 15 | // console.log('toJson : ', u8aToHex(pair.publicKey)); 16 | console.log('expect sign : ', u8aToHex(pair.sign(message, { withType: true }))); 17 | 18 | const ec = new EC('secp256k1'); 19 | const key = ec.keyFromPrivate(hexToU8a(secretKey)); 20 | const prepare = blake2AsU8a(message); 21 | 22 | console.log('prepare', u8aToHex(prepare)); 23 | const { s, r, recoveryParam } = key.sign(hexToU8a('0xac3b4f9fe406915078136ded365c88dfc226869ec21dfe235f6604db83418969')); 24 | console.log('r - ec :', r.toString('hex')); 25 | console.log('r - toHex :', u8aToHex(bnToU8a(r, EXPAND_OPT))); 26 | console.log('s - ec : ', s.toString('hex')); 27 | console.log('recoveryParam : ', recoveryParam); 28 | const receive = u8aConcat(bnToU8a(r, EXPAND_OPT), bnToU8a(s, EXPAND_OPT), new Uint8Array([recoveryParam || 0])); 29 | console.log('receive : ', u8aToHex(receive)); 30 | console.log('expect : ', u8aToHex(secp256k1Sign(message, { secretKey: hexToU8a(secretKey) }))); 31 | }); 32 | -------------------------------------------------------------------------------- /examples/ethereum/blockchain/docs/double-spent.md: -------------------------------------------------------------------------------- 1 | # Double spending 2 | 3 | Double-spending is the risk that a digital currency can be spent twice. It is a potential problem unique to digital currencies because digital information can be reproduced relatively easily by savvy individuals who understand the blockchain network and the computing power necessary to manipulate it. 4 | 5 | ## [see the sequence diagrams](https://mermaid-js.github.io/mermaid/#/sequenceDiagram?id=sequence-diagrams) 6 | 7 | ```mermaid 8 | %% double spending 9 | sequenceDiagram 10 | autonumber 11 | title: Double spending 12 | participant victim 13 | participant attack 14 | 15 | 16 | Note over victim: block 17 | 18 | attack->>victim: Connect 19 | attack-->>victim: Sync the victim's chain 20 | 21 | Note over victim: Block 22 | 23 | loop Sync victim's block 24 | par Sync victim's block 25 | Note over attack: sync victim's block 26 | and attack generate block 27 | Note over attack: block 28 | and victim generate block 29 | Note over victim: generate block 30 | end 31 | end 32 | 33 | attack-->>victim: Sync stop 34 | 35 | Note over attack: attack's block 36 | Note over victim: block 37 | Note over attack: attack's block 38 | 39 | attack->>+victim: Reconnect 40 | victim-->>attack: Sync start, because the hashrate of attacker is higher 41 | 42 | loop Sync attack's block 43 | par Sync attack's block 44 | Note over victim: attack's block 45 | Note right of victim: origin block 46 | Note over victim: attack's block 47 | Note right of victim: origin block 48 | and attack generate block 49 | Note over attack: block 50 | end 51 | end 52 | victim-->>attack: Sync end 53 | 54 | par victim generate block 55 | Note over victim: ledger block 56 | and attack generate block 57 | Note over attack: ledger block 58 | end 59 | 60 | ``` -------------------------------------------------------------------------------- /website/docs/crosschain/README.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 跨链技术文档 3 | description: 跨链桥接和协议的完整使用指南 4 | --- 5 | 6 | # 跨链技术文档 7 | 8 | 欢迎来到跨链技术文档!这里包含了使用各种跨链协议和桥接的完整指南。 9 | 10 | ## 📚 文档结构 11 | 12 | ### 基础概念 13 | - **[跨链技术介绍](./intro.md)** - 了解跨链技术的基本概念和应用场景 14 | 15 | ### AnySwap 协议 16 | - **[AnySwap 介绍](./anyswap/intro.md)** - AnySwap 协议概述和特性 17 | - **[ABI 编码和解码](./anyswap/abi.md)** - ABI 处理基础知识和实际应用 18 | - **[代币授权](./anyswap/approve.md)** - 代币授权操作和最佳实践 19 | - **[USDT 跨链转移](./anyswap/usdt-bridge.md)** - USDT 从 BSC 到 Polygon 的桥接 20 | - **[CLV 原生代币桥接](./anyswap/clv-bridge.md)** - CLV 原生代币的双向桥接 21 | - **[基本使用](./anyswap/basic-usage.md)** - 基于实际代码的基本使用方法 22 | - **[高级功能](./anyswap/advanced.md)** - 高级特性和优化技巧 23 | - **[常见问题](./anyswap/FAQ.md)** - 使用过程中的常见问题和解决方案 24 | 25 | ## 🚀 快速开始 26 | 27 | 1. **选择协议**: 根据你的需求选择合适的跨链协议 28 | 2. **了解基础**: 阅读相关协议的介绍文档 29 | 3. **查看示例**: 参考代码示例了解具体实现 30 | 4. **实践操作**: 在测试网上进行实际操作 31 | 5. **生产部署**: 在主网上部署你的应用 32 | 33 | ## 🔧 技术栈 34 | 35 | - **Node.js** - 运行环境 36 | - **ethers.js** - 以太坊交互库 37 | - **dotenv** - 环境变量管理 38 | - **AnySwap** - 跨链桥接协议 39 | 40 | ## 📖 学习路径 41 | 42 | ### 初学者 43 | 1. 阅读 [跨链技术介绍](./intro.md) 44 | 2. 了解 [AnySwap 协议](./anyswap/intro.md) 45 | 3. 学习 [ABI 编码和解码](./anyswap/abi.md) 46 | 4. 掌握 [代币授权](./anyswap/approve.md) 47 | 48 | ### 开发者 49 | 1. 实践 [USDT 跨链转移](./anyswap/usdt-bridge.md) 50 | 2. 学习 [CLV 原生代币桥接](./anyswap/clv-bridge.md) 51 | 3. 深入研究 [高级功能](./anyswap/advanced.md) 52 | 4. 参考 [常见问题](./anyswap/FAQ.md) 53 | 54 | ## 🛠️ 代码示例 55 | 56 | 所有文档都基于实际的代码示例,包括: 57 | 58 | - **ABI 处理** - 编码和解码函数调用 59 | - **代币授权** - 授权路由器使用代币 60 | - **资产桥接** - 在不同链间转移资产 61 | - **原生代币** - 桥接原生代币 62 | - **实际案例** - USDT 和 CLV 的完整桥接流程 63 | 64 | ## 🔒 安全提醒 65 | 66 | - 始终先在测试网上测试 67 | - 验证合约地址和网络配置 68 | - 了解相关风险和费用 69 | - 保护好你的私钥和助记词 70 | 71 | ## 📞 获取帮助 72 | 73 | - 查看 [常见问题](./anyswap/FAQ.md) 74 | - 参考官方文档 75 | 76 | --- 77 | 78 | *最后更新: 2024年* 79 | -------------------------------------------------------------------------------- /website/docs/aptos/intro.md: -------------------------------------------------------------------------------- 1 | # Aptos 开发指南 2 | 3 | 欢迎来到Aptos开发指南!本指南将帮助你掌握Aptos区块链开发的核心概念和实践技能。 4 | 5 | ## 什么是Aptos? 6 | 7 | Aptos是一个基于Move语言的Layer 1区块链平台,专注于安全性、可扩展性和可升级性。它使用拜占庭容错(BFT)共识机制,支持并行执行交易,并提供了强大的智能合约开发环境。 8 | 9 | ## 核心特性 10 | 11 | - **Move语言**: 资源导向的智能合约语言 12 | - **并行执行**: 支持交易并行处理 13 | - **BFT共识**: 拜占庭容错共识机制 14 | - **模块化架构**: 可升级的区块链基础设施 15 | - **资源模型**: 基于资源的账户模型 16 | 17 | ## 学习路径 18 | 19 | ### 1. 账户管理 20 | - [账户创建](./account/account.md) - 账户生成和密钥管理 21 | - [地址派生](./account/address.md) - 公钥到地址的转换 22 | 23 | ### 2. 代币操作 24 | - [代币转账](./token/transfer.md) - 基础代币转账 25 | - [自定义代币](./token/your-coin.md) - 创建和管理自定义代币 26 | - [代币余额](./token/balance.md) - 查询和管理代币余额 27 | 28 | ### 3. NFT功能 29 | - [NFT创建](./nft/nft.md) - NFT创建 30 | - [NFT转账](./nft/transfer.md) - NFT转账 31 | 32 | ### 4. 多重签名 33 | - [多签账户](./multisig/account.md) - 多重签名账户创建 34 | - [多签交易](./multisig/transaction.md) - 多签交易构建和签名 35 | 36 | ### 5. 交易处理 37 | - [交易构建](./tx/transaction.md) - 交易创建和签名 38 | - [交易提交](./tx/submit.md) - 交易广播和确认 39 | 40 | ## 开发工具 41 | 42 | - **Aptos SDK**: 官方TypeScript/JavaScript SDK 43 | - **Move**: 智能合约开发语言 44 | - **Aptos CLI**: 命令行工具 45 | - **Aptos Explorer**: 区块链浏览器 46 | 47 | ## 网络环境 48 | 49 | | 网络 | RPC URL | Faucet URL | 用途 | 50 | | ------ | -------------------------------------- | ------------------------------------ | -------- | 51 | | 主网 | https://fullnode.mainnet.aptoslabs.com | - | 生产环境 | 52 | | 测试网 | https://fullnode.testnet.aptoslabs.com | https://faucet.testnet.aptoslabs.com | 测试环境 | 53 | | 开发网 | https://fullnode.devnet.aptoslabs.com | https://faucet.devnet.aptoslabs.com | 开发测试 | 54 | 55 | ## 核心概念 56 | 57 | - **账户**: 每个账户都有唯一的地址和认证密钥 58 | - **资源**: Move语言中的核心概念,代表不可分割的数据 59 | - **模块**: 可重用的代码单元,包含函数和资源定义 60 | - **交易**: 状态转换的基本单位,包含payload和签名 61 | 62 | 开始你的Aptos开发之旅吧! 63 | -------------------------------------------------------------------------------- /website/src/components/ui/card.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | 3 | import { cn } from '../../lib/utils'; 4 | 5 | const Card = React.forwardRef>(({ className, ...props }, ref) => ( 6 |
7 | )); 8 | Card.displayName = 'Card'; 9 | 10 | const CardHeader = React.forwardRef>(({ className, ...props }, ref) => ( 11 |
12 | )); 13 | CardHeader.displayName = 'CardHeader'; 14 | 15 | const CardTitle = React.forwardRef>(({ className, ...props }, ref) => ( 16 |
17 | )); 18 | CardTitle.displayName = 'CardTitle'; 19 | 20 | const CardDescription = React.forwardRef>(({ className, ...props }, ref) => ( 21 |
22 | )); 23 | CardDescription.displayName = 'CardDescription'; 24 | 25 | const CardContent = React.forwardRef>(({ className, ...props }, ref) => ( 26 |
27 | )); 28 | CardContent.displayName = 'CardContent'; 29 | 30 | const CardFooter = React.forwardRef>(({ className, ...props }, ref) => ( 31 |
32 | )); 33 | CardFooter.displayName = 'CardFooter'; 34 | 35 | export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent }; 36 | -------------------------------------------------------------------------------- /website/src/components/ui/button.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { Slot } from '@radix-ui/react-slot'; 3 | import { cva, type VariantProps } from 'class-variance-authority'; 4 | 5 | import { cn } from '../../lib/utils'; 6 | 7 | const buttonVariants = cva( 8 | 'inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-hidden focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0', 9 | { 10 | variants: { 11 | variant: { 12 | default: 'bg-primary text-primary-foreground shadow-sm hover:bg-primary/90', 13 | destructive: 'bg-destructive text-destructive-foreground shadow-xs hover:bg-destructive/90', 14 | outline: 'border border-input bg-background shadow-xs hover:bg-accent hover:text-accent-foreground', 15 | secondary: 'bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80', 16 | ghost: 'hover:bg-accent hover:text-accent-foreground', 17 | link: 'text-primary underline-offset-4 hover:underline', 18 | }, 19 | size: { 20 | default: 'h-9 px-4 py-2', 21 | sm: 'h-8 rounded-md px-3 text-xs', 22 | lg: 'h-10 rounded-md px-8', 23 | icon: 'h-9 w-9', 24 | }, 25 | }, 26 | defaultVariants: { 27 | variant: 'default', 28 | size: 'default', 29 | }, 30 | }, 31 | ); 32 | 33 | export interface ButtonProps extends React.ButtonHTMLAttributes, VariantProps { 34 | asChild?: boolean; 35 | } 36 | 37 | const Button = React.forwardRef(({ className, variant, size, asChild = false, ...props }, ref) => { 38 | const Comp = asChild ? Slot : 'button'; 39 | return ; 40 | }); 41 | Button.displayName = 'Button'; 42 | 43 | export { Button, buttonVariants }; 44 | -------------------------------------------------------------------------------- /examples/ethereum/blockchain/README.MD: -------------------------------------------------------------------------------- 1 | # Ethereum Docker 2 | 3 | [ethereum-docker](https://github.com/Capgemini-AIE/ethereum-docker) 4 | 5 | ## Getting started 6 | 7 | ```sh 8 | mkdir -p data/{bootstrap,eth} 9 | ``` 10 | 11 | ## [Setup bootnode](https://geth.ethereum.org/docs/getting-started/private-net) 12 | 13 | ### genkey 14 | 15 | > bootnode -genkey bootnode.key 16 | 17 | ```sh 18 | b05a7c015501ce6c428844df2ff4cd63c98a9231987508430d51075a2e59faf6 19 | ``` 20 | 21 | ### nodekeyhex 22 | 23 | > bootnode -nodekeyhex b05a7c015501ce6c428844df2ff4cd63c98a9231987508430d51075a2e59faf6 24 | 25 | ```sh 26 | enode://90168cc33f18e900606ccfd62f72d10c90d21f03463a8b083d6d92fa4545b6551312f75551d47d53b166aa918ac7495dba087effc3408c2da0c716c9022f10b3@127.0.0.1:0?discport=30301 27 | Note: you're using cmd/bootnode, a developer tool. 28 | We recommend using a regular node as bootstrap node for production deployments. 29 | INFO [07-27|17:27:07.377] New local node record seq=1 id=bf81e45805a470c5 ip= udp=0 tcp=0 30 | ``` 31 | 32 | ## run compose 33 | 34 | > docker compose up 35 | 36 | ## mining 37 | 38 | ### attach the geth 39 | 40 | ```sh 41 | docker compose exec bootstrap bash 42 | 43 | bash-5.1# geth attach ipc://root/.ethereum/devchain/geth.ipc 44 | Welcome to the Geth JavaScript console! 45 | 46 | instance: Geth/v1.10.6-unstable-f05419f0-20210715/linux-amd64/go1.16.6 47 | at block: 0 (Tue Jul 27 2021 08:34:08 GMT+0000 (UTC)) 48 | datadir: /root/.ethereum/devchain 49 | modules: admin:1.0 debug:1.0 eth:1.0 ethash:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0 50 | 51 | To exit, press ctrl-d 52 | ``` 53 | 54 | ### prepare account 55 | 56 | ```sh 57 | > personal.newAccount() 58 | Passphrase: 59 | Repeat passphrase: 60 | "0x57a15b6138cb454bdc094d90fb07adb2f52c26d4" 61 | ``` 62 | 63 | ### start mining 64 | 65 | ```sh 66 | > miner.start() 67 | null 68 | ``` 69 | 70 | ### tail logs 71 | 72 | ![logs](./images/1627379241363.jpg) 73 | 74 | ### web 75 | 76 | ![web](./images/1627379455441.jpg) 77 | -------------------------------------------------------------------------------- /elliptic/ed25519.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * libraries 3 | * : noble-curves(https://github.com/paulmillr/noble-curves) 4 | * : tweetnacl-js(https://github.com/dchest/tweetnacl-js) 5 | */ 6 | import { ed25519 } from '@noble/curves/ed25519'; 7 | import { randomBytes, bytesToHex, utf8ToBytes } from '@noble/hashes/utils'; 8 | import nacl from 'tweetnacl'; 9 | import assert from 'node:assert/strict'; 10 | import crypto from 'node:crypto'; 11 | 12 | export function tweetnacl() { 13 | const hashToSign = randomBytes(32); 14 | const privateKey = randomBytes(32); 15 | const keyPair = nacl.sign.keyPair.fromSeed(privateKey); 16 | const secretKey = keyPair.secretKey; 17 | 18 | // public key 19 | const publicKey = ed25519.getPublicKey(privateKey); 20 | assert.strictEqual(bytesToHex(publicKey), bytesToHex(keyPair.publicKey), 'publicKey do not match'); 21 | 22 | // signature 23 | const signature = ed25519.sign(hashToSign, privateKey); 24 | assert.strictEqual(bytesToHex(signature), bytesToHex(nacl.sign.detached(hashToSign, secretKey)), 'signatures do not match'); 25 | 26 | // verify signature 27 | assert.strict(ed25519.verify(signature, hashToSign, publicKey), 'noble ed25519 signature verify failed'); 28 | assert.strict(nacl.sign.detached.verify(hashToSign, signature, publicKey), 'tweetnacl ed25519 signature verify failed'); 29 | 30 | console.log('All tests passed'); 31 | } 32 | 33 | export function nodejs() { 34 | const type = 'ed25519'; 35 | const { publicKey, privateKey } = crypto.generateKeyPairSync(type); 36 | const message = 'Hello world!'; 37 | const signature = crypto.sign(null, utf8ToBytes(message), privateKey); 38 | const verified = crypto.verify(null, utf8ToBytes(message), publicKey, signature); 39 | console.log('signature : ', bytesToHex(signature)); 40 | console.log('privateKey : ', privateKey.export({ format: 'der', type: 'pkcs8' }).toString('hex')); 41 | console.log('isMatch : ', verified); 42 | console.log('generated complete. \n'); 43 | } 44 | 45 | function main() { 46 | tweetnacl(); 47 | nodejs(); 48 | } 49 | 50 | main(); 51 | -------------------------------------------------------------------------------- /examples/solana/account/address.ts: -------------------------------------------------------------------------------- 1 | import assert from 'node:assert'; 2 | import { Keypair } from '@solana/web3.js'; 3 | import { toBase58 } from '@sola-hq/toolkit'; 4 | import nacl from 'tweetnacl'; 5 | 6 | import * as bip39 from 'bip39'; 7 | import { HDKey } from 'micro-ed25519-hdkey'; 8 | import { bytesToHex, hexToBytes } from '@noble/hashes/utils'; 9 | 10 | /** 11 | * @param mnemonic - The mnemonic phrase to derive the keypair from. 12 | * @param password - The password to use for the mnemonic. 13 | * @param index - The index to use for the derivation path. 14 | * @returns The derived keypair. 15 | */ 16 | function mnemonicToKeypair(mnemonic: string, password: string = '', index: number = 0) { 17 | const seed = bip39.mnemonicToSeedSync(mnemonic, password); 18 | const hd = HDKey.fromMasterSeed(seed.toString('hex')); 19 | const path = `m/44'/501'/${index}'/0'`; 20 | const derivedSeed = hd.derive(path).privateKey; 21 | return Keypair.fromSeed(derivedSeed); 22 | } 23 | 24 | /** 25 | * @returns The generated keypair. 26 | */ 27 | function generateRandomKeypair() { 28 | // 生成新的随机密钥对 29 | const keypair = Keypair.generate(); 30 | console.log('Public Key:', keypair.publicKey.toBase58()); 31 | console.log('Secret Key:', toBase58(keypair.secretKey)); 32 | console.log('Address :', keypair.publicKey.toBase58()); 33 | return keypair; 34 | } 35 | 36 | function main() { 37 | const mnemonic = process.env.MNEMONIC; 38 | const message = hexToBytes('8001000102'); 39 | const keypair = mnemonicToKeypair(mnemonic); 40 | 41 | console.log('keypair publicKey : ', keypair.publicKey.toBase58()); 42 | console.log('keypair secretKey : ', toBase58(keypair.secretKey)); 43 | console.log('address : ', keypair.publicKey.toBase58()); 44 | const signature = nacl.sign.detached(message, keypair.secretKey); 45 | assert.strict(nacl.sign.detached.verify(message, signature, keypair.publicKey.toBuffer()), 'tweetnacl ed25519 signature verify failed'); 46 | console.log('signature : ', bytesToHex(signature)); 47 | console.log('bs58 : ', toBase58(signature)); 48 | } 49 | 50 | main(); 51 | -------------------------------------------------------------------------------- /examples/umi/tx/tx.js: -------------------------------------------------------------------------------- 1 | require('dotenv').config(); 2 | const umi = require('@umi-top/umi-core-js'); 3 | var mnemonic = process.env.UMI_MNEMONIC; 4 | 5 | const bip39 = require('bip39'); 6 | // var mnemonic = bip39.generateMnemonic(256); 7 | 8 | const seed = bip39.mnemonicToSeedSync(mnemonic); 9 | const secKey = umi.SecretKey.fromSeed(seed); 10 | 11 | const sender = umi.Address.fromKey(secKey).setPrefix('umi'); 12 | // const recipient = umi.Address.fromKey(secKey).setPrefix('aaa'); 13 | const recipient = umi.Address.fromBech32('umi1244pgspze5cvy2wv96fyr0v5z6js7cfkluwdsm624pcj5aps2fnsy60s7j'); 14 | 15 | console.log('sender : ', sender.getBech32()); 16 | console.log('recipient : ', recipient.getBech32()); 17 | var tx = new umi.Transaction().setVersion(8).setSender(sender).setRecipient(recipient).setValue(10); 18 | 19 | // tx = tx.setNonce(1635841272027); 20 | // var message = tx.getBytes().slice(0, 85); 21 | 22 | // console.log('message : ', umi.hexEncode(message)); 23 | // var signature = secKey.sign(message); 24 | // console.log('signature : ', umi.hexEncode(signature)); 25 | 26 | // var tx = umi.Transaction.fromBytes(umi.hexDecode('0155a92202fce93e6fd225e0e4e029de1a671d24e0d4b60445bd9e4f8c2da31cbc05e255a9556a144022cd30c229cc2e9241bd9416a50f6136ff1cd86f4aa8712a7430526700000000000000640000017ce028b9030000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000')); 27 | // console.log('tx bytes 1.: ', umi.hexEncode(tx.getBytes())); 28 | // var signature = secKey.sign(umi.hexDecode('0155a92202fce93e6fd225e0e4e029de1a671d24e0d4b60445bd9e4f8c2da31cbc05e255a9556a144022cd30c229cc2e9241bd9416a50f6136ff1cd86f4aa8712a7430526700000000000000640000017ce028b903')); 29 | // console.log('signature : ', umi.hexEncode(signature)); 30 | // tx = tx.setSignature(signature); 31 | 32 | tx = tx.sign(secKey); 33 | 34 | console.log('tx bytes 2.: ', umi.hexEncode(tx.getBytes())); 35 | console.log('txid : ', umi.hexEncode(tx.getHash())); 36 | console.log('base64 : ', umi.base64Encode(tx.getBytes())); 37 | // console.log('expected : ', expected === umi.base64Encode(tx.getBytes())); 38 | -------------------------------------------------------------------------------- /website/blog/2024-01-15-bitcoin-script-system.md: -------------------------------------------------------------------------------- 1 | --- 2 | slug: bitcoin-script-system 3 | title: 比特币脚本系统详解 - 从理论到实践 4 | authors: [iamnivekx] 5 | tags: [bitcoin, script, blockchain, development] 6 | --- 7 | 8 | 比特币脚本系统是比特币网络的核心组件之一,它定义了如何验证交易的有效性。本文将深入探讨比特币脚本的工作原理,并通过实际代码示例来展示如何操作脚本。 9 | 10 | 以下代码参考 bitcoinjs-lib 的实现, 并进行了一些修改. 请参考 [bitcoinjs-lib](https://github.com/bitcoinjs/bitcoinjs-lib) 了解更多信息. 11 | 12 | 13 | 14 | ## 什么是比特币脚本? 15 | 16 | 比特币脚本是一种基于栈的编程语言,用于定义比特币交易的解锁和锁定条件。每个比特币交易都包含输入脚本(scriptSig)和输出脚本(scriptPubKey),通过执行这些脚本来验证交易的有效性。 17 | 18 | ## 核心功能模块 19 | 20 | ### 1. 脚本编译 (compile) 21 | 22 | 脚本编译是将脚本块(chunks)转换为字节码的过程: 23 | 24 | ```ts file=/examples/bitcoin/script.ts#L29-L74 showLineNumbers 25 | 26 | compile 27 | ``` 28 | 29 | ### 2. 脚本反编译 (decompile) 30 | 31 | 反编译是将字节码转换回脚本块的过程: 32 | 33 | ```ts file=/examples/bitcoin/script.ts#L76-L111 showLineNumbers 34 | ``` 35 | 36 | ### 3. ASM 格式转换 37 | 38 | 比特币脚本支持人类可读的 ASM(Assembly)格式: 39 | 40 | ```ts file=/examples/bitcoin/script.ts#L113-L150 showLineNumbers 41 | ``` 42 | 43 | ## 实际应用示例 44 | 45 | ### 创建 P2PKH 脚本 46 | 47 | ```ts 48 | // 创建一个标准的 P2PKH 脚本 49 | const pubkeyHash = Buffer.from('1234567890abcdef1234567890abcdef12345678', 'hex'); 50 | const p2pkhScript = [ 51 | OPS.OP_DUP, 52 | OPS.OP_HASH160, 53 | pubkeyHash, 54 | OPS.OP_EQUALVERIFY, 55 | OPS.OP_CHECKSIG 56 | ]; 57 | 58 | const compiledScript = compile(p2pkhScript); 59 | console.log('Compiled script:', compiledScript.toString('hex')); 60 | ``` 61 | 62 | ### 验证公钥格式 63 | 64 | ```ts 65 | const pubkey = Buffer.from('02...', 'hex'); // 你的公钥 66 | if (isCanonicalPubKey(pubkey)) { 67 | console.log('Valid canonical public key'); 68 | } else { 69 | console.log('Invalid public key format'); 70 | } 71 | ``` 72 | 73 | ## 最小推送策略 (BIP62.3) 74 | 75 | 比特币脚本遵循最小推送策略,确保数据以最紧凑的方式表示: 76 | 77 | ```ts file=/examples/bitcoin/script.ts#L13-L18 showLineNumbers 78 | ``` 79 | 80 | ## 总结 81 | 82 | 比特币脚本系统提供了强大的灵活性来定义各种交易条件。通过理解脚本的编译、反编译和 ASM 格式转换,开发者可以: 83 | 84 | 1. 创建自定义的交易类型 85 | 2. 验证交易脚本的有效性 86 | 3. 调试和优化脚本性能 87 | 4. 实现复杂的智能合约逻辑 88 | 89 | 在下一篇文章中,我们将探讨比特币地址的生成和验证机制。 -------------------------------------------------------------------------------- /examples/crosschain/anyswap/approve.js: -------------------------------------------------------------------------------- 1 | 2 | require('dotenv').config(); 3 | const { utils, Wallet, providers } = require('ethers'); 4 | 5 | const mnemonic = process.env.CROSS_CHAIN_MNEMONIC; 6 | 7 | const iface = new utils.Interface([ 8 | 'function approve(address spender, uint256 amount)', 9 | ]); 10 | 11 | async function approve() { 12 | var wallet = Wallet.fromMnemonic(mnemonic); 13 | const address = await wallet.getAddress(); 14 | console.log('wallet : ', address); 15 | 16 | var url = 'https://bsc-dataseed2.binance.org/'; 17 | 18 | var router = '0xd1c5966f9f5ee6881ff6b261bbeda45972b1b5f3'; 19 | var token = '0xEDF0c420bc3b92B961C6eC411cc810CA81F5F21a'; 20 | var amount = '115792089237316195423570985008687907853269984665640564039457584007913129639935'; 21 | const provider = new providers.JsonRpcProvider(url); 22 | const network = await provider.getNetwork(); 23 | const chainId = network.chainId; 24 | 25 | const { gasPrice } = await provider.getFeeData(); 26 | 27 | const balance = await provider.getBalance(address); 28 | const nonce = await provider.getTransactionCount(address); 29 | console.log('balance : ', balance); 30 | 31 | var input = iface.encodeFunctionData('approve', [router, amount]); 32 | 33 | const txData = { 34 | // type: 1, 35 | chainId, 36 | nonce, 37 | to: token, 38 | data: input, 39 | 40 | value: '0x00', 41 | 42 | gasPrice, 43 | // maxFeePerGas, 44 | // maxPriorityFeePerGas, 45 | } 46 | 47 | const gasLimit = await provider.estimateGas({ ...txData, from: address }); 48 | var unsignedTx = { 49 | ...txData, 50 | gasLimit, 51 | } 52 | 53 | const message = utils.keccak256(utils.serializeTransaction(unsignedTx)); 54 | // var signature = wallet._signingKey().signDigest(utils.arrayify(message)); 55 | 56 | // var signedTx = utils.serializeTransaction(unsignedTx, signature); 57 | // var tx = utils.parseTransaction(signedTx); 58 | // console.log('signed tx : ', tx); 59 | 60 | var signedTx = await wallet.signTransaction(unsignedTx); 61 | 62 | var { hash } = await provider.sendTransaction(signedTx); 63 | console.log('txHash : ', hash); 64 | } 65 | approve().catch(console.error); -------------------------------------------------------------------------------- /examples/ethereum/blockchain/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '2' 2 | services: 3 | bootstrap: 4 | build: monitored-geth-client 5 | restart: on-failure 6 | container_name: bootstrap 7 | hostname: bootstrap 8 | mem_limit: 2G 9 | cpus: 1 10 | links: 11 | - netstats 12 | entrypoint: /root/start.sh 13 | command: '--datadir=~/.ethereum/devchain --syncmode full --http --http.addr 0.0.0.0 --http.vhosts ,* --http.api personal,eth,net,web3,admin,miner --ws --ws.addr 0.0.0.0 --ws.api eth,debug,admin --networkid=666 --txlookuplimit 0 --gcmode archive --allow-insecure-unlock --snapshot=false --rpc.allow-unprotected-txs' 14 | # '--datadir /chain/data --syncmode full --http --http.addr 0.0.0.0 --http.vhosts ,* --http.api eth,debug,admin --ws --ws.addr 0.0.0.0 --ws.api eth,debug,admin --txlookuplimit 0 --gcmode archive 15 | volumes: 16 | - ./data/bootstrap:/root/.ethereum 17 | - ./files/genesis.json:/root/files/genesis.json:ro 18 | - ./files/localtime:/etc/localtime:ro 19 | ports: 20 | - '30303:30303' 21 | - '30303:30303/udp' 22 | - '8545:8545' 23 | # eth: 24 | # build: monitored-geth-client 25 | # restart: on-failure 26 | # container_name: eth 27 | # hostname: eth 28 | # mem_limit: 2G 29 | # cpus: 1 30 | # links: 31 | # - bootstrap 32 | # - netstats 33 | # entrypoint: /root/start.sh 34 | # volumes: 35 | # - ./data/eth:/root/.ethereum 36 | # - ./files/genesis.json:/root/files/genesis.json:ro 37 | # - ./files/localtime:/etc/localtime:ro 38 | # ports: 39 | # - '40303:30303' 40 | # - '40303:30303/udp' 41 | # - '18545:8545' 42 | # command: '--datadir=~/.ethereum/devchain --rpcapi "db,personal,eth,net,web3,admin,miner" --rpccorsdomain="*" --networkid=666 --rpc --rpcaddr="0.0.0.0" --allow-insecure-unlock' 43 | netstats: 44 | build: eth-netstats 45 | restart: on-failure 46 | container_name: netstats 47 | environment: 48 | - WS_SECRET=eth-net-stats-secret 49 | volumes: 50 | - ./files/localtime:/etc/localtime:ro 51 | ports: 52 | - '3000:3000' 53 | -------------------------------------------------------------------------------- /examples/bitcoin/tx/bch.v1.js: -------------------------------------------------------------------------------- 1 | require('dotenv').config(); 2 | 3 | const rp = require('request-promise'); 4 | const coinSelect = require('coinselect'); 5 | const { Transaction, TransactionBuilder, networks, ECPair, script } = require('@bitgo/utxo-lib'); 6 | 7 | var secret = process.env.ECDSA_SECRET; 8 | 9 | async function getUTXOS(address, bitcoreURI = 'https://api.bitcore.io/api/BCH/testnet') { 10 | return rp({ 11 | url: `${bitcoreURI}/address/${address}?unspent=true`, 12 | method: 'GET', 13 | json: true, 14 | headers: { 15 | 'Content-Type': 'application/json', 16 | }, 17 | }); 18 | } 19 | 20 | async function buildTx(input) { 21 | const network = networks.bitcoincashTestnet; 22 | 23 | const keyPair = ECPair.fromPrivateKeyBuffer(Buffer.from(secret, 'hex'), network); 24 | 25 | const amount = input.value - 1000; 26 | 27 | const pk = keyPair.getPublicKeyBuffer(); 28 | const spk = script.pubKey.output.encode(pk); 29 | const txb = new TransactionBuilder(network); 30 | 31 | console.log('pk', pk.toString('hex')); 32 | console.log('address', keyPair.getAddress()); 33 | 34 | txb.addInput(input.mintTxid, input.mintIndex, Transaction.DEFAULT_SEQUENCE); 35 | txb.addOutput('mjNTKjpkusZfjmA8fD6vrCy2irPmwcrGen', amount); 36 | txb.setVersion(2); 37 | 38 | const hashType = Transaction.SIGHASH_ALL | Transaction.SIGHASH_BITCOINCASHBIP143; 39 | txb.sign(0, keyPair, null, hashType, input.value); 40 | 41 | const serialized = txb.build().toHex(); 42 | console.log(serialized); 43 | } 44 | 45 | async function utxo(address, feeRate) { 46 | const utxos = await getUTXOS(address); 47 | const receipts = [ 48 | { 49 | address: 'mjNTKjpkusZfjmA8fD6vrCy2irPmwcrGen', 50 | value: 997000, 51 | }, 52 | ]; 53 | 54 | const { inputs, outputs } = coinSelect(utxos, receipts, feeRate); 55 | if (!inputs || !outputs) return; 56 | console.log('outputs', outputs); 57 | console.log('inputs', inputs); 58 | 59 | buildTx(inputs[0], outputs); 60 | } 61 | 62 | const address = 'qq4yfl0qucg68wh3a80kgz58ed5sz5kdfvj5muw894'; 63 | const feeRate = 1; 64 | utxo(address, feeRate).then().catch(console.error); 65 | -------------------------------------------------------------------------------- /elliptic/secp256k1.ts: -------------------------------------------------------------------------------- 1 | import 'dotenv/config'; 2 | 3 | import { bytesToHex, hexToBytes } from '@noble/hashes/utils'; 4 | import { ECDSASignature, ecsign, toBytes } from '@ethereumjs/util'; 5 | import * as ecc from 'tiny-secp256k1'; 6 | 7 | import { ec as EC } from 'elliptic'; 8 | const ec = new EC('secp256k1'); 9 | 10 | type Signature = Pick; 11 | 12 | function canonical({ r, s, recoveryParam }: Signature): Signature { 13 | if (s.cmp(ec.nh) > 0) { 14 | s = ec.n.sub(s); 15 | recoveryParam ^= 1; 16 | } 17 | 18 | return { r, s, recoveryParam }; 19 | } 20 | 21 | function display(signature: ECDSASignature) { 22 | const r = toBytes(signature.r); 23 | const s = toBytes(signature.s); 24 | const v = signature.v; 25 | console.log('r : ', bytesToHex(r)); // 26 | console.log('s : ', bytesToHex(s)); 27 | console.log('v : ', v); 28 | console.log('r + s : ', bytesToHex(Buffer.concat([r, s]))); 29 | console.log('r + s + v: ', bytesToHex(Buffer.concat([r, s])) + toBytes(v)); 30 | } 31 | 32 | var secret = process.env.ECDSA_SECRET; 33 | var msg = '0f555ff76600d72613417599a74db3a6e159000f96c770ed37d99e9deb429ae1'; 34 | var privKey = Buffer.from(secret, 'hex'); 35 | var signature = ec.sign(msg, privKey); 36 | 37 | const keyPair = ec.keyFromPrivate(privKey); 38 | console.log('pub hex : ', keyPair.getPublic(true, 'hex')); 39 | display({ 40 | r: signature.r.toBuffer(), 41 | s: signature.s.toBuffer(), 42 | v: BigInt(signature.recoveryParam), 43 | }); 44 | 45 | var expected = ecc.sign(Buffer.from(msg, 'hex'), privKey); 46 | console.log('ecc : ', bytesToHex(expected)); 47 | 48 | var canonicate = canonical(signature); 49 | console.log('---------------'); 50 | console.log('-- canonical --'); 51 | console.log('---------------'); 52 | display({ 53 | r: canonicate.r.toBuffer(), 54 | s: canonicate.s.toBuffer(), 55 | v: BigInt(canonicate.recoveryParam), 56 | }); 57 | console.log('---------------'); 58 | console.log('------end------'); 59 | console.log('---------------'); 60 | 61 | const msgHash = hexToBytes(msg); 62 | var signed = ecsign(msgHash, privKey); 63 | display(signed); 64 | -------------------------------------------------------------------------------- /website/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "website", 3 | "version": "0.0.0", 4 | "private": true, 5 | "scripts": { 6 | "docusaurus": "docusaurus", 7 | "start": "docusaurus start", 8 | "build": "docusaurus build", 9 | "swizzle": "docusaurus swizzle", 10 | "deploy": "docusaurus deploy", 11 | "clear": "docusaurus clear", 12 | "serve": "docusaurus serve", 13 | "write-translations": "docusaurus write-translations", 14 | "write-heading-ids": "docusaurus write-heading-ids", 15 | "typecheck": "tsc" 16 | }, 17 | "dependencies": { 18 | "@docusaurus/core": "3.8.1", 19 | "@docusaurus/faster": "3.8.1", 20 | "@docusaurus/plugin-content-blog": "^3.8.1", 21 | "@docusaurus/plugin-ideal-image": "3.8.1", 22 | "@docusaurus/preset-classic": "3.8.1", 23 | "@docusaurus/remark-plugin-npm2yarn": "^3.8.1", 24 | "@docusaurus/theme-mermaid": "^3.8.1", 25 | "@easyops-cn/docusaurus-search-local": "^0.52.1", 26 | "@mdx-js/react": "^3.1.0", 27 | "@radix-ui/react-avatar": "^1.1.10", 28 | "@radix-ui/react-slot": "^1.2.3", 29 | "class-variance-authority": "^0.7.1", 30 | "clsx": "^2.0.0", 31 | "lucide-react": "^0.540.0", 32 | "prism-react-renderer": "^2.4.1", 33 | "react": "^19.0.0", 34 | "react-dom": "^19.0.0" 35 | }, 36 | "devDependencies": { 37 | "@docusaurus/module-type-aliases": "3.8.1", 38 | "@docusaurus/tsconfig": "^3.8.1", 39 | "@docusaurus/types": "3.8.1", 40 | "@tailwindcss/postcss": "^4.0.12", 41 | "autoprefixer": "^10.4.21", 42 | "postcss": "^8.5.6", 43 | "prettier-plugin-tailwindcss": "^0.6.14", 44 | "rehype-katex": "^7.0.1", 45 | "remark-code-import": "^1.2.0", 46 | "remark-math": "^6.0.0", 47 | "tailwind-merge": "^3.3.1", 48 | "tailwindcss": "^4.1.12", 49 | "tailwindcss-animate": "^1.0.7", 50 | "typescript": "^5.9.2" 51 | }, 52 | "browserslist": { 53 | "production": [ 54 | ">0.5%", 55 | "not dead", 56 | "not op_mini all" 57 | ], 58 | "development": [ 59 | "last 3 chrome version", 60 | "last 3 firefox version", 61 | "last 5 safari version" 62 | ] 63 | }, 64 | "engines": { 65 | "node": ">=18.0" 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /website/blog/2024-01-18-bitcoin-transaction-building.md: -------------------------------------------------------------------------------- 1 | --- 2 | slug: bitcoin-transaction-building 3 | title: 比特币交易构建与签名 - 完整实践指南 4 | authors: [iamnivekx] 5 | tags: [bitcoin, transaction, psbt, signature, bitcoinjs-lib] 6 | --- 7 | 8 | 比特币交易的构建和签名是区块链开发中的核心技能。本文将详细介绍如何使用比特币工具包构建各种类型的比特币交易,包括输入选择、输出创建、签名和广播。 9 | 10 | 11 | 12 | ## 交易构建基础 13 | 14 | ### 1. 环境设置 15 | 16 | 首先需要安装我们的比特币工具包: 17 | 18 | ```ts file=/examples/bitcoin/address/address.ts showLineNumbers 19 | 20 | ``` 21 | 22 | ### 2. 密钥管理 23 | 24 | ```ts file=/examples/bitcoin/address/address.ts showLineNumbers 25 | 26 | ``` 27 | 28 | ## PSBT 交易构建 29 | 30 | PSBT (Partially Signed Bitcoin Transaction) 是现代比特币交易的标准格式。 31 | 32 | ```ts file=/examples/bitcoin/tx/bitcoin.js showLineNumbers 33 | 34 | ``` 35 | 36 | ## 不同类型的交易构建 37 | 38 | ### 1. 地址生成 39 | 40 | ```ts file=/examples/bitcoin/address/address.ts showLineNumbers 41 | 42 | ``` 43 | 44 | ### 2. 多签名交易 45 | 46 | ```ts file=/examples/bitcoin/address/multisig.ts showLineNumbers 47 | 48 | ``` 49 | 50 | ## 交易签名 51 | 52 | ### 1. 单签名 53 | 54 | ```ts file=/examples/bitcoin/tx/bitcoin.js showLineNumbers 55 | 56 | ``` 57 | 58 | ### 2. 多签名 59 | 60 | ```ts file=/examples/bitcoin/tx/bitcoin.js#L15-L42 showLineNumbers 61 | 62 | ``` 63 | 64 | ## RBF (Replace-By-Fee) 交易 65 | 66 | RBF 允许用更高手续费的交易替换未确认的交易。 67 | 68 | ```ts file=/examples/bitcoin/tx/rbf.js showLineNumbers 69 | 70 | ``` 71 | 72 | ## 交易验证 73 | 74 | ```ts 75 | 76 | ``` 77 | 78 | ## 交易广播 79 | 80 | 交易广播通常通过比特币节点或第三方 API 服务进行。你可以使用以下方式之一: 81 | 82 | 1. **本地比特币节点**: 使用 `bitcoin-cli sendrawtransaction` 83 | 2. **第三方 API**: 如 Blockstream、BlockCypher 等 84 | 3. **测试网**: 使用测试网 API 进行开发和测试 85 | 86 | ## 完整交易流程示例 87 | 88 | ```ts 89 | 90 | ``` 91 | 92 | ## 安全最佳实践 93 | 94 | 1. **私钥安全**: 永远不要在代码中硬编码私钥 95 | 2. **网络选择**: 开发时使用测试网,生产时使用主网 96 | 3. **手续费计算**: 动态计算手续费以确保交易被确认 97 | 4. **输入验证**: 始终验证 UTXO 的有效性和所有权 98 | 5. **错误处理**: 实现完善的错误处理和回滚机制 99 | 100 | ## 总结 101 | 102 | 比特币交易构建是一个复杂但重要的过程。通过掌握 PSBT、各种交易类型和签名机制,开发者可以: 103 | 104 | - 构建安全的比特币应用 105 | - 实现复杂的交易逻辑 106 | - 支持多种地址格式 107 | - 优化交易费用和确认时间 108 | 109 | 在下一篇文章中,我们将探讨比特币工具函数和实用技巧。 110 | -------------------------------------------------------------------------------- /examples/ripple/tx/codec.js: -------------------------------------------------------------------------------- 1 | const codec = require('ripple-binary-codec'); 2 | 3 | const data = { 4 | TransactionType: 'Payment', 5 | Account: 'rfXgErjK96k59evDnC22zX7vRo2hYaSiqc', 6 | Amount: '1000000', 7 | Destination: 'rUCzEr6jrEyMpjhs4wSdQdz4g8Y382NxfM', 8 | Flags: 2147483648, 9 | LastLedgerSequence: 19193162, 10 | Fee: '12', 11 | Sequence: 19165274, 12 | SigningPubKey: '035ABF78147D2CAB552A4CCE6067457023100E9B9A8B4B097847428B0F03216669', 13 | // TxnSignature: '30440220733FD472FC9D554C3A439D66F457A6E5FD17DFC17372CF2CDDC50A9D43E4EA97022066F01DCACF63CD9DC219464632922E676669536E01D898AFAF029470DDE86354', 14 | }; 15 | 16 | const expected = 17 | '12000022800000002401285BA82E00003039201B01285C056140000000000F42406840000000000000187446304402204FE6BC5E6B9D09B228C9F380C161C5223E64CBA0F05A62D1BE66A26C10CA3FD50220314FA9195FF2B591491D84D4C01913E86EFFC2909BA957186161D4561FC9821181145128798CDDE9DCA099454B5702CB0730688F5CB183142A44FDE0E611A3BAF1E9DF640A87CB690152CD4B'; 18 | const serialized = codec.encode(data); 19 | 20 | console.log(expected === serialized); 21 | // 1200002280000000240124705A201B0124E27A6140000000000F424068400000000000000C7321035ABF78147D2CAB552A4CCE6067457023100E9B9A8B4B097847428B0F0321666974473045022100DD4AEB145ED63B11863B54F24AFB42D7753D87E1BCA0EFCA7271DB4F1FC084DA02205A290B99A543872D738D95AAB293AE30B869A6E7799567714799D869726E30E58114479DFDA47DC5E11BFF00A06888164CAD3793B8C283148008F9193579C7D32FAF4AD1A9BFFDB236F148E3 22 | // 12000022800000002401285BA82E00003039201B01285C056140000000000F42406840000000000000187446304402204FE6BC5E6B9D09B228C9F380C161C5223E64CBA0F05A62D1BE66A26C10CA3FD50220314FA9195FF2B591491D84D4C01913E86EFFC2909BA957186161D4561FC9821181145128798CDDE9DCA099454B5702CB0730688F5CB183142A44FDE0E611A3BAF1E9DF640A87CB690152CD4B 23 | const decode = codec.decode( 24 | '12000022800000002401285BA82E00003039201B0128635B6140000000000F4240684000000000000018732102F4147DA97162A214DBE25828EE4C4ACC4DC721CD0C15B2761B43ED0292ED82B57446304402201762B75663D48CA3511F46F315A13EC9EDAD808D8E2657C31F6BE44D067CB1C8022027B95CE8C5E852AEF457AC6AF634EB27808669E421FD629A6E0ADDEF8B9404AD81145128798CDDE9DCA099454B5702CB0730688F5CB183142A44FDE0E611A3BAF1E9DF640A87CB690152CD4B', 25 | ); 26 | console.log('decode : ', decode); 27 | 28 | const hash = codec.encodeForSigning(data); 29 | console.log('hash', hash); 30 | -------------------------------------------------------------------------------- /examples/ripple/tx/sign-external.js: -------------------------------------------------------------------------------- 1 | const _ = require('lodash'); 2 | const RippleAPI = require('ripple-lib').RippleAPI; 3 | const codec = require('ripple-binary-codec'); 4 | 5 | const api = new RippleAPI({ 6 | server: 'wss://s.altnet.rippletest.net/', // Public rippled server 7 | }); 8 | 9 | // Address: rfXgErjK96k59evDnC22zX7vRo2hYaSiqc 10 | // Secret: ssHAaRfvdDsF62da3dpDHgxHSnw4d 11 | // Balance: 1,000 XRP 12 | 13 | const from_address = 'rfXgErjK96k59evDnC22zX7vRo2hYaSiqc'; 14 | const secret = 'ssHAaRfvdDsF62da3dpDHgxHSnw4d'; 15 | const dest_address = 'rUCzEr6jrEyMpjhs4wSdQdz4g8Y382NxfM'; 16 | 17 | async function main() { 18 | await api.connect(); 19 | 20 | const account = await api.getAccountInfo(from_address); 21 | console.log('account', account); 22 | 23 | const preparedTx = await api.prepareTransaction( 24 | { 25 | TransactionType: 'Payment', 26 | Account: from_address, 27 | Amount: api.xrpToDrops('1'), 28 | Destination: 'rUCzEr6jrEyMpjhs4wSdQdz4g8Y382NxfM', 29 | }, 30 | { 31 | // Expire this transaction if it doesn't execute within ~5 minutes: 32 | // maxFee 33 | maxLedgerVersionOffset: 75, 34 | }, 35 | ); 36 | 37 | console.log('prepare', preparedTx); 38 | const tmp = JSON.parse(preparedTx.txJSON); 39 | console.log('tmp', tmp); 40 | const serialized = codec.encode(tmp); 41 | console.log('Transaction serialized:', serialized); 42 | const maxLedgerVersion = preparedTx.instructions.maxLedgerVersion; 43 | console.log('Prepared transaction instructions:', preparedTx.txJSON); 44 | console.log('Transaction cost:', preparedTx.instructions.fee, 'XRP'); 45 | console.log('Transaction expires after ledger:', maxLedgerVersion); 46 | 47 | const signed = api.sign(preparedTx.txJSON, secret); 48 | const txID = signed.id; 49 | const tx_signed = signed.signedTransaction; 50 | console.log('Identifying hash:', txID); 51 | console.log('Signed tx:', tx_signed); 52 | 53 | // const ledgerVersion = await api.getLedgerVersion(); 54 | // const earliestLedgerVersion = ledgerVersion + 1; 55 | 56 | const result = await api.submit(tx_signed); 57 | console.log('Tentative result code:', result.resultCode); 58 | console.log('Tentative result message:', result.resultMessage); 59 | 60 | return api.disconnect(); 61 | } 62 | 63 | main().then().catch(console.error); 64 | -------------------------------------------------------------------------------- /website/docs/ton/README.md: -------------------------------------------------------------------------------- 1 | # TON 开发文档 2 | 3 | 欢迎来到 TON 开发文档!这里包含了完整的 TON 区块链开发指南,从基础概念到高级应用。 4 | 5 | ## 📚 文档结构 6 | 7 | ### 1. 账户管理 8 | - **[账户创建与管理](./account/account.md)** - 私钥、公钥、地址生成 9 | - **[钱包集成](./account/wallet.md)** - 钱包创建、管理和操作 10 | 11 | ### 2. 交易处理 12 | - **[交易构建与签名](./tx/send-ton.md)** - 交易创建、签名和验证 13 | 14 | ### 3. 代币操作 15 | - **[Jetton代币操作](./token/jetton.md)** - Jetton代币转账和授权 16 | 17 | ## 🚀 快速开始 18 | 19 | ### 环境准备 20 | ```bash 21 | # 安装依赖 22 | npm install @ton/ton @ton/core @ton/crypto 23 | 24 | # 或者使用yarn 25 | yarn add @ton/ton @ton/core @ton/crypto 26 | ``` 27 | 28 | ### 创建客户端 29 | ```typescript 30 | import { TonClient } from '@ton/ton'; 31 | 32 | const client = new TonClient({ 33 | endpoint: 'https://toncenter.com/api/v2/jsonRPC', 34 | apiKey: 'YOUR_API_KEY' 35 | }); 36 | ``` 37 | 38 | ### 创建钱包 39 | ```typescript 40 | import { mnemonicToPrivateKey } from '@ton/crypto'; 41 | import { WalletContractV4 } from '@ton/ton'; 42 | 43 | const mnemonics = 'your mnemonic phrase here'; 44 | const keyPair = await mnemonicToPrivateKey(mnemonics.split(' ')); 45 | 46 | const wallet = WalletContractV4.create({ 47 | workchain: 0, 48 | publicKey: keyPair.publicKey 49 | }); 50 | const contract = client.open(wallet); 51 | ``` 52 | 53 | ## 🔧 开发工具 54 | 55 | - **@ton/ton** - TON 区块链官方 JavaScript 库 56 | - **@ton/core** - TON 核心功能库 57 | - **@ton/crypto** - 加密和密钥管理库 58 | - **TonCenter API** - TON 区块链数据访问 59 | 60 | ## 🌐 网络环境 61 | 62 | | 网络 | 用途 | 状态 | 63 | | ------ | -------- | ------ | 64 | | 主网 | 生产环境 | ✅ 活跃 | 65 | | 测试网 | 开发测试 | ✅ 活跃 | 66 | 67 | ## 📖 学习路径 68 | 69 | ### 初学者 70 | 1. 了解 TON 基础概念 71 | 2. 学习账户和钱包管理 72 | 3. 掌握基本交易操作 73 | 74 | ### 进阶开发者 75 | 1. 深入理解 Jetton 代币 76 | 2. 学习智能合约交互 77 | 3. 掌握地址格式转换 78 | 79 | ### 高级开发者 80 | 1. 构建 DeFi 应用 81 | 2. 优化交易费用 82 | 3. 实现复杂业务逻辑 83 | 84 | ## 🤝 贡献指南 85 | 86 | 欢迎贡献代码和文档!请遵循以下步骤: 87 | 88 | 1. Fork 本仓库 89 | 2. 创建特性分支 90 | 3. 提交更改 91 | 4. 推送到分支 92 | 5. 创建 Pull Request 93 | 94 | ## 📞 支持 95 | 96 | 如果你遇到问题或需要帮助: 97 | 98 | - 查看 [常见问题](./FAQ.md) 99 | - 提交 [Issue](https://github.com/iamnivekx/blockchain-notes/issues) 100 | 101 | ## 📄 许可证 102 | 103 | 本项目采用 MIT 许可证 - 查看 [LICENSE](https://github.com/iamnivekx/blockchain-notes/blob/main/LICENSE) 文件了解详情。 104 | 105 | --- 106 | 107 | **开始你的 TON 开发之旅吧!** 🚀 108 | -------------------------------------------------------------------------------- /examples/tron/account/address.js: -------------------------------------------------------------------------------- 1 | const TronWeb = require('tronweb'); 2 | const utils = TronWeb.utils; 3 | 4 | const { ec: EC } = require('elliptic'); 5 | const ec = new EC('secp256k1'); 6 | 7 | function genPriKey() { 8 | const ec = new EC('secp256k1'); 9 | const key = ec.genKeyPair(); 10 | const priKey = key.getPrivate(); 11 | const pubKeyHex = key.getPublic(false, 'hex'); 12 | 13 | let priKeyHex = priKey.toString('hex'); 14 | 15 | while (priKeyHex.length < 64) { 16 | priKeyHex = `0${priKeyHex}`; 17 | } 18 | console.log('priKeyHex', priKeyHex); 19 | console.log('pubKeyHex', pubKeyHex); 20 | console.log('fromPrivateKey(privateKey)', TronWeb.address.fromPrivateKey(priKeyHex)); 21 | return utils.code.hexStr2byteArray(priKeyHex); 22 | } 23 | 24 | // const priKey = genPriKey(); 25 | // const com_addrBytes = utils.crypto.getAddressFromPriKey(priKey); 26 | // const base58Addr = utils.crypto.getBase58CheckAddress(com_addrBytes); 27 | // console.log('base58Addr', base58Addr); 28 | 29 | // const bytes = utils.crypto.genPriKey(); 30 | // const hexStr = utils.bytes.byteArray2hexStr(bytes); 31 | // console.log('hexStr', hexStr); 32 | 33 | const privateKey = ''; 34 | const publicKey = ''; 35 | 36 | const pair = ec.keyFromPublic(publicKey, 'hex'); 37 | const decompose = pair.getPublic(false, 'hex'); 38 | 39 | const com_priKeyBytes = utils.code.hexStr2byteArray(privateKey); 40 | const pubBytes = utils.crypto.getPubKeyFromPriKey(com_priKeyBytes); 41 | console.log('pub hex: ', utils.code.byteArray2hexStr(pubBytes)); 42 | 43 | const com_addressBytes = utils.crypto.computeAddress(pubBytes); 44 | const base58 = utils.crypto.getBase58CheckAddress(com_addressBytes); 45 | 46 | console.log('pubBytes', pubBytes); 47 | const com_pubKeyBytes = utils.code.hexStr2byteArray(decompose); 48 | 49 | console.log('pub key to address : ', utils.crypto.getBase58CheckAddress(utils.crypto.computeAddress(com_pubKeyBytes))); 50 | console.log('priv to address : ', TronWeb.address.fromPrivateKey(privateKey)); 51 | console.log('priv to address : ', base58); 52 | console.log(); 53 | console.log('expected addr', 'TBHyRnhWGUpbrFBwZEyxgSQa7rKWvLCej3'); 54 | // console.log('priv to address', TronWeb.utils.crypto.fromPrivateKey('02ff26c5980685ae12d25312a8df8224c951a68272013425ffa60327d7d4b54231')); 55 | // const address = tronWeb.address.fromHex('418840E6C55B9ADA326D211D818C34A994AECED808'); 56 | // console.log('address', address); 57 | -------------------------------------------------------------------------------- /examples/ripple/account/check.js: -------------------------------------------------------------------------------- 1 | const base = require('base-x'); 2 | const { classicAddressToXAddress, decodeAccountID } = require('ripple-address-codec'); 3 | const RippleAPI = require('ripple-lib').RippleAPI; 4 | const bs58 = base('rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz'); 5 | 6 | const api = new RippleAPI({}); 7 | 8 | // rsuUYDM8d15J44pZbdKumiDcnXHjPEuhXE 9 | // sapyGYwE3bh3JiYU59hFdecU2PovC 10 | 11 | // r9jhVPMfEWv2YCP7TNKoqyPUScUt66Hkuq 12 | // snv63YPxpLsqn7NsdGxnqECviNPZ2 13 | 14 | const secret = 'sapyGYwE3bh3JiYU59hFdecU2PovC'; 15 | const keypair = api.deriveKeypair(secret); 16 | const { publicKey, privateKey } = keypair; 17 | const address = api.deriveAddress(publicKey); 18 | console.log('publicKey : ', publicKey); 19 | console.log('privateKey : ', privateKey); 20 | const xAddress = classicAddressToXAddress(address, false, true); 21 | const xTestAddress = classicAddressToXAddress(address, false, false); 22 | console.log('address : ', address); 23 | console.log('x Addr : ', xAddress); 24 | console.log('x TestAddr : ', xTestAddress); 25 | 26 | function seqEqual(arr1, arr2) { 27 | if (arr1.length !== arr2.length) { 28 | return false; 29 | } 30 | for (let i = 0; i < arr1.length; i++) { 31 | if (arr1[i] !== arr2[i]) { 32 | return false; 33 | } 34 | } 35 | return true; 36 | } 37 | 38 | function isValidAddress(address) { 39 | const expectedLength = 20; 40 | const withoutSum = decodeChecked(address); 41 | const versionBytes = withoutSum.slice(0, -expectedLength); 42 | if (seqEqual(versionBytes, [0])) { 43 | return true; 44 | } 45 | return false; 46 | } 47 | 48 | function decodeChecked(base58string) { 49 | const buffer = bs58.decode(base58string); 50 | if (buffer.length < 5) { 51 | throw new Error('invalid_input_size: decoded data must have length >= 5'); 52 | } 53 | if (!verifyCheckSum(buffer)) { 54 | throw new Error('checksum_invalid'); 55 | } 56 | return buffer.slice(0, -4); 57 | } 58 | 59 | function verifyCheckSum(bytes) { 60 | const computed = sha256(sha256(bytes.slice(0, -4))).slice(0, 4); 61 | const checksum = bytes.slice(-4); 62 | return seqEqual(computed, checksum); 63 | } 64 | 65 | { 66 | const address = 'rDogsAY9kUNG3b4U3NjFa447MhA5zsLXp'; 67 | const valid = isValidAddress(address); 68 | console.log('isValid', valid); 69 | const decode = decodeAccountID(address); 70 | console.log('decode', decode); 71 | } 72 | -------------------------------------------------------------------------------- /examples/avalanche/sign-external.js: -------------------------------------------------------------------------------- 1 | require('dotenv').config(); 2 | const { Avalanche, BinTools, Buffer, avm, utils } = require('avalanche'); 3 | const { Serialization } = utils; 4 | const bintools = BinTools.getInstance(); 5 | const serialization = Serialization.getInstance(); 6 | const { SECRET_KEY_1 } = process.env; 7 | const avalanche = new Avalanche('api.avax-test.network', 443, 'https', 5); 8 | const xchain = avalanche.XChain(); //returns a reference to the X-Chain used by AvalancheJS 9 | 10 | const myKeyChain = xchain.keyChain(); 11 | 12 | async function main() { 13 | var msg = serialization.bufferToType(Buffer.from('c74f28c8abbe0a4f656eab6a70980d7bd8849ed53972cfb75dd461b7e8d15f18', 'hex'), 'cb58'); 14 | console.log('msg', msg); 15 | const KeyPair = avm.KeyPair; 16 | var kp = new KeyPair(myKeyChain.hrp, myKeyChain.chainid); 17 | 18 | const keyPair = myKeyChain.importKey(Buffer.from(SECRET_KEY_1, 'hex')); 19 | var pub_hex = keyPair.getPublicKey().toString('hex'); 20 | console.log('pub hex : ', pub_hex); 21 | console.log('addr : ', keyPair.getAddressString()); 22 | console.log('addr buf : ', keyPair.getAddress().toString('hex')); 23 | 24 | var expected_signature = 25 | '4e9b4279d46e2d1d967a3558210743fde1b51950932dd8cf426ed96790da4f706f41cee97924f47ab160850db4e3b09039afd5053e958486f927822c93c229f101'; 26 | var signature = keyPair.sign(msg); 27 | console.log('signature : ', signature.toString('hex')); 28 | console.log('signature eq: ', signature.toString('hex') === expected_signature); 29 | var kp = new avm.KeyPair(myKeyChain.hrp, myKeyChain.chainid); 30 | 31 | const addr = KeyPair.addressFromPublicKey(keyPair.getPublicKey()); 32 | // kp['pubk'] = kpPub; 33 | const type = 'bech32'; 34 | var addrString = serialization.bufferToType(addr, type, myKeyChain.hrp, myKeyChain.chainid); 35 | 36 | console.log('pub buf : ', addrString); 37 | console.log('addr : ', keyPair.getAddressString()); 38 | console.log('addr buf : ', keyPair.getAddress().toString('hex')); 39 | console.log('addr : ', kp.getAddressString()); 40 | console.log('addr buf : ', kp.getAddress().toString('hex')); 41 | console.log('pub hex : ', keyPair.getPublicKey().toString('hex')); 42 | return; 43 | 44 | // const balance = await xchain.getBalance(address, 'AVAX'); 45 | // console.log('balance', balance); 46 | // console.log('newAddress1', newAddress1.getAddress()); 47 | } 48 | 49 | main().catch(console.error); 50 | -------------------------------------------------------------------------------- /examples/ripple/multisig/account.js: -------------------------------------------------------------------------------- 1 | const RippleAPI = require('ripple-lib').RippleAPI; 2 | 3 | const api = new RippleAPI({ 4 | server: 'wss://s.altnet.rippletest.net/', // Public rippled server 5 | }); 6 | 7 | const from_address = 'rfXgErjK96k59evDnC22zX7vRo2hYaSiqc'; 8 | const secret = 'ssHAaRfvdDsF62da3dpDHgxHSnw4d'; 9 | 10 | async function main() { 11 | await api.connect(); 12 | 13 | const account = await api.getAccountInfo(from_address); 14 | console.log('account', account); 15 | 16 | const preparedTx = await api.prepareTransaction( 17 | { 18 | Flags: 0, 19 | TransactionType: 'SignerListSet', 20 | Account: from_address, 21 | Fee: '10000', 22 | SignerQuorum: 3, 23 | SignerEntries: [ 24 | { 25 | SignerEntry: { 26 | Account: 'r3Q3D8nsyu2nJKFsagHfYdMp8H1VEHd3ps', 27 | SignerWeight: 2, 28 | }, 29 | }, 30 | { 31 | SignerEntry: { 32 | Account: 'rhiWpgj8ai3QxegWAe3ZpHk6iionnbtAz1', 33 | SignerWeight: 1, 34 | }, 35 | }, 36 | { 37 | SignerEntry: { 38 | Account: 'r3DtjVnBbAf63zryETCjx8NG2j3ewNcJ9g', 39 | SignerWeight: 1, 40 | }, 41 | }, 42 | ], 43 | }, 44 | // { 45 | // // Expire this transaction if it doesn't execute within ~5 minutes: 46 | // // maxFee 47 | // // maxLedgerVersionOffset: 75, 48 | // } 49 | ); 50 | 51 | console.log('prepare', preparedTx); 52 | 53 | const maxLedgerVersion = preparedTx.instructions.maxLedgerVersion; 54 | console.log('Prepared transaction instructions:', preparedTx.txJSON); 55 | console.log('Transaction cost:', preparedTx.instructions.fee, 'XRP'); 56 | console.log('Transaction expires after ledger:', maxLedgerVersion); 57 | 58 | const signed = api.sign(preparedTx.txJSON, secret); 59 | const txID = signed.id; 60 | const tx_signed = signed.signedTransaction; 61 | console.log('Identifying hash:', txID); 62 | console.log('Signed tx:', tx_signed); 63 | 64 | // const ledgerVersion = await api.getLedgerVersion(); 65 | // const earliestLedgerVersion = ledgerVersion + 1; 66 | 67 | const sresult = await api.submit(tx_signed); 68 | console.log('Tentative result code:', result.resultCode); 69 | console.log('Tentative result message:', result.resultMessage); 70 | 71 | return api.disconnect(); 72 | } 73 | 74 | main().then().catch(console.error); 75 | -------------------------------------------------------------------------------- /website/docs/ripple/intro.md: -------------------------------------------------------------------------------- 1 | # Ripple 快速入门 2 | 3 | 欢迎来到 Ripple 快速入门指南!本指南基于你的实际代码实现,帮助你快速上手 Ripple 区块链开发。 4 | 5 | ## 🚀 快速开始 6 | 7 | ### 1. 安装依赖 8 | ```bash 9 | npm install ripple-lib ripple-address-codec ripple-binary-codec 10 | npm install lodash base-x 11 | ``` 12 | 13 | ### 2. 连接网络 14 | ```javascript 15 | const RippleAPI = require('ripple-lib').RippleAPI; 16 | 17 | const api = new RippleAPI({ 18 | server: 'wss://s.altnet.rippletest.net/', // 测试网 19 | }); 20 | 21 | await api.connect(); 22 | ``` 23 | 24 | ### 3. 生成地址 25 | ```javascript 26 | const secret = 'sapyGYwE3bh3JiYU59hFdecU2PovC'; 27 | const keypair = api.deriveKeypair(secret); 28 | const address = api.deriveAddress(keypair.publicKey); 29 | console.log('Address:', address); 30 | ``` 31 | 32 | ## 🌟 核心特性 33 | 34 | - **快速交易**: 3-5秒确认时间 35 | - **低费用**: 每笔交易仅需0.00001 XRP 36 | - **多重签名**: 支持最多8个签名者 37 | - **跨链兼容**: 支持多种资产和代币 38 | - **地址格式**: 经典地址和X地址支持 39 | 40 | ## 📚 学习路径 41 | 42 | ### 1. 账户管理 43 | - [地址生成](./account/address.md) - 生成和管理 Ripple 地址 44 | - [账户检查](./account/check.md) - 验证地址和查询账户信息 45 | - [账户启用](./account/enable.md) - 激活和配置账户 46 | - [账户标志](./account/flag.md) - 设置账户标志 47 | 48 | ### 2. 交易处理 49 | - [SDK交易](./tx/sign-sdk.md) - 使用SDK交易创建、签名和提交 50 | - [离线交易](./tx/sign-external.md) - 使用离线交易处理和签名 51 | - [HTTP交易](./tx/http.md) - 通过HTTP接口处理 52 | - [交易编码](./tx/codec.md) - 交易序列化 53 | 54 | ### 3. 多重签名 55 | - [多重签名账户](./multisig/account.md) - 创建多重签名账户 56 | - [多重签名交易](./multisig/tx.md) - 处理多重签名交易 57 | - [多重签名启用](./multisig/enable.md) - 启用多重签名功能 58 | 59 | ## 🛠️ 开发工具 60 | 61 | - **ripple-lib** - 官方JavaScript SDK 62 | - **ripple-address-codec** - 地址编码库 63 | - **ripple-binary-codec** - 交易序列化库 64 | - **base-x** - Base58编码库 65 | - **lodash** - 实用工具库 66 | 67 | ## 🌐 网络环境 68 | 69 | | 网络 | RPC URL | 状态 | 用途 | 70 | | ---------- | ------------------------------ | -------- | -------- | 71 | | **主网** | wss://s1.ripple.com/ | ✅ 活跃 | 生产环境 | 72 | | **测试网** | wss://s.altnet.rippletest.net/ | ✅ 活跃 | 开发测试 | 73 | | **开发网** | wss://s.devnet.rippletest.net/ | 🔧 可配置 | 开发测试 | 74 | 75 | ## 🏗️ 技术架构 76 | 77 | ### 共识机制 78 | - **共识协议** - 基于拜占庭容错的共识 79 | - **验证节点** - 去中心化验证网络 80 | - **区块确认** - 3-5秒快速确认 81 | 82 | ### 账户类型 83 | - **经典地址** - 传统Ripple地址格式 84 | - **X地址** - 新的地址格式,支持标签 85 | - **多重签名** - 多签名者账户 86 | 87 | ## 🚀 下一步 88 | 89 | - 查看 [完整开发文档](./README.md) 90 | - 开始 [地址生成](./account/address.md) 91 | - 学习 [SDK交易](./tx/sign-sdk.md) 92 | - 探索 [多重签名](./multisig/account.md) 93 | 94 | 开始你的 Ripple 开发之旅吧! 95 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | lerna-debug.log* 8 | 9 | **/.private.key 10 | **/.private.json 11 | **/.private.js 12 | **/*.tar.gz 13 | **/*.zip 14 | **/*.tar 15 | **/*.gz 16 | **/*.bz2 17 | **/*.rar 18 | **/*.7z 19 | 20 | # Diagnostic reports (https://nodejs.org/api/report.html) 21 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 22 | 23 | # Runtime data 24 | pids 25 | *.pid 26 | *.seed 27 | *.pid.lock 28 | 29 | # Directory for instrumented libs generated by jscoverage/JSCover 30 | lib-cov 31 | 32 | # Coverage directory used by tools like istanbul 33 | coverage 34 | *.lcov 35 | 36 | # nyc test coverage 37 | .nyc_output 38 | 39 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 40 | .grunt 41 | 42 | # Bower dependency directory (https://bower.io/) 43 | bower_components 44 | 45 | # node-waf configuration 46 | .lock-wscript 47 | 48 | # Compiled binary addons (https://nodejs.org/api/addons.html) 49 | build/Release 50 | 51 | # Dependency directories 52 | node_modules/ 53 | jspm_packages/ 54 | 55 | # TypeScript v1 declaration files 56 | typings/ 57 | 58 | # TypeScript cache 59 | *.tsbuildinfo 60 | 61 | # Optional npm cache directory 62 | .npm 63 | 64 | # Optional eslint cache 65 | .eslintcache 66 | 67 | # Microbundle cache 68 | .rpt2_cache/ 69 | .rts2_cache_cjs/ 70 | .rts2_cache_es/ 71 | .rts2_cache_umd/ 72 | 73 | # Optional REPL history 74 | .node_repl_history 75 | 76 | # Output of 'npm pack' 77 | *.tgz 78 | 79 | # Yarn Integrity file 80 | .yarn-integrity 81 | 82 | # dotenv environment variables file 83 | .env 84 | .env.test 85 | 86 | # parcel-bundler cache (https://parceljs.org/) 87 | .cache 88 | 89 | # Next.js build output 90 | .next 91 | 92 | # Nuxt.js build / generate output 93 | .nuxt 94 | dist 95 | 96 | # Gatsby files 97 | .cache/ 98 | # Comment in the public line in if your project uses Gatsby and *not* Next.js 99 | # https://nextjs.org/blog/next-9-1#public-directory-support 100 | # public 101 | 102 | # vuepress build output 103 | .vuepress/dist 104 | 105 | # Serverless directories 106 | .serverless/ 107 | 108 | # FuseBox cache 109 | .fusebox/ 110 | 111 | # DynamoDB Local files 112 | .dynamodb/ 113 | 114 | # TernJS port file 115 | .tern-port 116 | 117 | .DS_Store 118 | 119 | .env 120 | *.env 121 | *.keystore 122 | 123 | **/data 124 | **/.vscode 125 | 126 | private.js 127 | *.rs.bk 128 | *.bk 129 | 130 | *.zip 131 | 132 | GEMINI.md 133 | cursor.md -------------------------------------------------------------------------------- /examples/ton/wallet.ts: -------------------------------------------------------------------------------- 1 | import { KeyPair, mnemonicToPrivateKey } from '@ton/crypto'; 2 | import { TonClient, WalletContractV3R2, WalletContractV4, WalletContractV5R1 } from '@ton/ton'; 3 | 4 | import 'dotenv/config'; 5 | 6 | // Create Client 7 | const client = new TonClient({ 8 | endpoint: 'https://toncenter.com/api/v2/jsonRPC', 9 | apiKey: process.env.TON_API_KEY, 10 | }); 11 | 12 | // https://github.com/ton-org/ton/blob/master/src/wallets/WalletContractV3R2.spec.ts 13 | async function walletV3R2(keyPair: KeyPair) { 14 | const workchain = 0; // Usually you need a workchain 0 15 | // Create wallet contract 16 | const wallet = WalletContractV3R2.create({ workchain, publicKey: keyPair.publicKey }); 17 | const contract = client.open(wallet); 18 | const address = contract.address.toString({ bounceable: false, urlSafe: true }); 19 | console.log('v3r2 address', address); 20 | // Get balance 21 | const balance: bigint = await contract.getBalance(); 22 | console.log('balance', balance); 23 | return contract; 24 | } 25 | 26 | // https://github.com/ton-org/ton/blob/master/src/wallets/WalletContractV4.spec.ts 27 | async function walletV4R2(keyPair: KeyPair) { 28 | const workchain = 0; // Usually you need a workchain 0 29 | // Create wallet contract 30 | const wallet = WalletContractV4.create({ workchain, publicKey: keyPair.publicKey }); 31 | const contract = client.open(wallet); 32 | const address = contract.address.toString({ bounceable: false, urlSafe: true }); 33 | console.log('v4r2 address', address); 34 | // Get balance 35 | const balance: bigint = await contract.getBalance(); 36 | console.log('balance', balance); 37 | 38 | return contract; 39 | } 40 | 41 | // https://github.com/ton-org/ton/blob/master/src/wallets/v5r1/WalletContractV5R1.spec.ts 42 | async function walletV5R1(keyPair: KeyPair) { 43 | // Create wallet contract 44 | const wallet = WalletContractV5R1.create({ publicKey: keyPair.publicKey }); 45 | const contract = client.open(wallet); 46 | const address = contract.address.toString({ bounceable: false, urlSafe: true }); 47 | console.log('v5 address', address); 48 | // Get balance 49 | const balance: bigint = await contract.getBalance(); 50 | console.log('balance', balance); 51 | return contract; 52 | } 53 | 54 | async function main() { 55 | const mnemonics = process.env.TON_MNEMONIC; 56 | const keyPair = await mnemonicToPrivateKey(mnemonics.split(' ')); 57 | await walletV3R2(keyPair); 58 | 59 | await walletV4R2(keyPair); 60 | 61 | await walletV5R1(keyPair); 62 | } 63 | 64 | main().catch(console.error); 65 | -------------------------------------------------------------------------------- /examples/ripple/multisig/enable.js: -------------------------------------------------------------------------------- 1 | const RippleAPI = require('ripple-lib').RippleAPI; 2 | 3 | const api = new RippleAPI({ 4 | server: 'wss://s.altnet.rippletest.net/', // Public rippled server 5 | }); 6 | 7 | const jon = { 8 | account: 'rGtkPCrTgq5st3uSsyz5YnHMETYQdQofUS', 9 | secret: 'snuALrXSwbTHpWft3ibTA9ZzszC22', 10 | }; 11 | const aya = { 12 | account: 'rhV1ZJ5SHs8Spbu4aXjAE225a1CzfoJnru', 13 | secret: 'sndxPdZnfUzxKyaB6XwFsnETwrtTX', 14 | }; 15 | const bran = { 16 | account: 'rweTZdJmr67cVuWnqqUQbUqcDGugpnRehc', 17 | secret: 'ss2Zoo3b7DvbijGxrD8TtSatHCohU', 18 | }; 19 | 20 | // const from_address = 'rfXgErjK96k59evDnC22zX7vRo2hYaSiqc'; 21 | // const secret = 'ssHAaRfvdDsF62da3dpDHgxHSnw4d'; 22 | 23 | const from_address = 'rDerjU2jeRvGmRDpfRoSFkbYen4dXzuSrH'; 24 | const secret = 'snQ8ipa9zdwX1taPZCmLq5RLNTrJR'; 25 | 26 | async function main() { 27 | await api.connect(); 28 | 29 | const account = await api.getAccountInfo(from_address); 30 | console.log('account', account); 31 | 32 | const preparedTx = await api.prepareTransaction( 33 | { 34 | TransactionType: 'AccountSet', 35 | Account: from_address, 36 | ClearFlag: 4, 37 | }, 38 | { 39 | // Expire this transaction if it doesn't execute within ~5 minutes: 40 | signersCount: 2, 41 | }, 42 | ); 43 | console.log('prepare', preparedTx); 44 | // return; 45 | 46 | const maxLedgerVersion = preparedTx.instructions.maxLedgerVersion; 47 | console.log('Prepared transaction instructions:', preparedTx.txJSON); 48 | console.log('Transaction cost:', preparedTx.instructions.fee, 'XRP'); 49 | console.log('Transaction expires after ledger:', maxLedgerVersion); 50 | 51 | // return; 52 | const jonSign = api.sign(preparedTx.txJSON, jon.secret, { signAs: jon.account }).signedTransaction; 53 | const ayaSign = api.sign(preparedTx.txJSON, aya.secret, { signAs: aya.account }).signedTransaction; 54 | 55 | // signatures are combined and submitted 56 | const combinedTx = api.combine([jonSign, ayaSign]); 57 | 58 | const tx_signed = combinedTx.signedTransaction; 59 | const txID = combinedTx.id; 60 | console.log('Identifying hash:', txID); 61 | console.log('Signed tx:', tx_signed); 62 | 63 | // const ledgerVersion = await api.getLedgerVersion(); 64 | // const earliestLedgerVersion = ledgerVersion + 1; 65 | 66 | // return; 67 | const result = await api.submit(tx_signed); 68 | console.log('Tentative result code:', result.resultCode); 69 | console.log('Tentative result message:', result.resultMessage); 70 | 71 | return api.disconnect(); 72 | } 73 | 74 | main().then().catch(console.error); 75 | -------------------------------------------------------------------------------- /examples/ethereum/tx/transaction.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert'); 2 | const { ethers, utils } = require('ethers') 3 | const { TransactionFactory } = require('@ethereumjs/tx'); 4 | const { default: Common, Hardfork } = require('@ethereumjs/common'); 5 | 6 | const privateKey = ''; 7 | 8 | async function ethereumjs(chainId, txData) { 9 | const common = Common.custom(chainId, { hardfork: Hardfork.London, chain: chainId }) 10 | const typedTransaction = TransactionFactory.fromTxData(txData, { common }); 11 | const messageTosign = typedTransaction.getMessageToSign(true); 12 | const message = utils.hexlify(messageTosign); 13 | const request = { 14 | ...typedTransaction.toJSON(), 15 | chainId, 16 | type: typedTransaction.type, 17 | } 18 | const serializedTransaction = ethers.utils.serializeTransaction(request); 19 | const msg = ethers.utils.keccak256(serializedTransaction); 20 | 21 | assert.strictEqual(msg, message, 'message mismatch'); 22 | const signedTransaction = typedTransaction.sign(Buffer.from(privateKey, 'hex')); 23 | return utils.hexlify(signedTransaction.hash()); 24 | } 25 | 26 | async function ethersjs(chainId, txData) { 27 | const unsignedTransaction = { 28 | ...txData, 29 | chainId, 30 | } 31 | const message = ethers.utils.keccak256(ethers.utils.serializeTransaction(unsignedTransaction)); 32 | 33 | const wallet = new ethers.Wallet(privateKey); 34 | const signature = wallet._signingKey().signDigest(ethers.utils.arrayify(message)); 35 | 36 | const signedTransacion = utils.serializeTransaction(unsignedTransaction, signature); 37 | const hash = ethers.utils.keccak256(signedTransacion) 38 | return hash; 39 | } 40 | 41 | // https://goerli.etherscan.io/tx/0x6d9a2610589239b175d50a70c640fb659e7d3c75390fff98fc52dd543c63c097 42 | async function main() { 43 | // const endpoint = 'https://goerli.infura.io/v3/you_key'; 44 | // const provider = ethers.providers.JsonRpcProvider(endpoint); 45 | 46 | const chainId = 5; 47 | const hash = '0x6d9a2610589239b175d50a70c640fb659e7d3c75390fff98fc52dd543c63c097'; 48 | const txData = { 49 | chainId, 50 | gasLimit: "0x5208", 51 | "accessList": [], 52 | "data": "0x", 53 | "maxFeePerGas": "0x59682f1e", 54 | "maxPriorityFeePerGas": "0x59682f00", 55 | "nonce": "0x76", 56 | "to": "0x2501a57b3625f9762698097c72e3ec06f8de1ee7", 57 | "type": 2, 58 | "value": "0x38d7ea4c68000" 59 | }; 60 | const ethereumjsHash = await ethereumjs(chainId, txData); 61 | const ethersjsHash = await ethersjs(chainId, txData); 62 | assert.strictEqual(ethereumjsHash, hash, 'ethereumjs hash mismatch'); 63 | assert.strictEqual(ethersjsHash, hash, 'ethersjs hash mismatch'); 64 | } 65 | 66 | main().catch(console.error) -------------------------------------------------------------------------------- /examples/aptos/transfer_coin.ts: -------------------------------------------------------------------------------- 1 | import { AptosClient, AptosAccount, CoinClient, FaucetClient, HexString } from "aptos"; 2 | 3 | const NODE_URL = 'https://fullnode.testnet.aptoslabs.com'; 4 | const FAUCET_URL = 'https://faucet.testnet.aptoslabs.com'; 5 | 6 | const alice = new AptosAccount() 7 | const bob = new AptosAccount() 8 | 9 | // https://github.com/aptos-labs/aptos-core/blob/main/ecosystem/typescript/sdk/examples/typescript/transfer_coin.ts 10 | async function main() { 11 | // Create API and faucet clients. 12 | // :!:>section_1 13 | const client = new AptosClient(NODE_URL); 14 | const faucetClient = new FaucetClient(NODE_URL, FAUCET_URL); // <:!:section_1 15 | 16 | // Create client for working with the coin module. 17 | // :!:>section_1a 18 | const coinClient = new CoinClient(client); // <:!:section_1a 19 | 20 | // Create accounts. 21 | // :!:>section_2 22 | // const alice = new AptosAccount(); 23 | // const bob = new AptosAccount(); // <:!:section_2 24 | 25 | // Print out account addresses. 26 | console.log("=== Addresses ==="); 27 | console.log(`Alice: ${alice.address()}`); 28 | console.log(`Bob: ${bob.address()}`); 29 | console.log(""); 30 | 31 | // Fund accounts. 32 | // :!:>section_3 33 | // await faucetClient.fundAccount(alice.address(), 100_000_000); 34 | // await faucetClient.fundAccount(bob.address(), 0); // <:!:section_3 35 | 36 | // Print out initial balances. 37 | console.log("=== Initial Balances ==="); 38 | // :!:>section_4 39 | console.log(`Alice: ${await coinClient.checkBalance(alice)}`); 40 | console.log(`Bob: ${await coinClient.checkBalance(bob)}`); // <:!:section_4 41 | console.log(""); 42 | 43 | // Have Alice send Bob some AptosCoins. 44 | // :!:>section_5 45 | let txnHash = await coinClient.transfer(alice, bob, 1_000, { gasUnitPrice: BigInt(100) }); // <:!:section_5 46 | // :!:>section_6a 47 | await client.waitForTransaction(txnHash); // <:!:section_6a 48 | 49 | // Print out intermediate balances. 50 | console.log("=== Intermediate Balances ==="); 51 | console.log(`Alice: ${await coinClient.checkBalance(alice)}`); 52 | console.log(`Bob: ${await coinClient.checkBalance(bob)}`); 53 | console.log(""); 54 | 55 | // Have Alice send Bob some more AptosCoins. 56 | txnHash = await coinClient.transfer(alice, bob, 1_000, { gasUnitPrice: BigInt(100) }); 57 | // :!:>section_6b 58 | await client.waitForTransaction(txnHash, { checkSuccess: true }); // <:!:section_6b 59 | 60 | // Print out final balances. 61 | console.log("=== Final Balances ==="); 62 | console.log(`Alice: ${await coinClient.checkBalance(alice)}`); 63 | console.log(`Bob: ${await coinClient.checkBalance(bob)}`); 64 | console.log(""); 65 | } 66 | 67 | main().catch(console.error) -------------------------------------------------------------------------------- /examples/cosmos/tx/decode.js: -------------------------------------------------------------------------------- 1 | const { 2 | DirectSecp256k1HdWallet, 3 | Registry, 4 | makeAuthInfoBytes, 5 | encodePubkey, 6 | decodePubkey, 7 | makeSignDoc, 8 | makeSignBytes, 9 | } = require('@cosmjs/proto-signing'); 10 | const { fromBase64, toBase64, toHex, fromHex } = require('@cosmjs/encoding'); 11 | const { pubkeyType, pubkeyToAddress, encodeSecp256k1Pubkey } = require('@cosmjs/amino'); 12 | const crypto = require('@cosmjs/crypto'); 13 | const { 14 | defaultRegistryTypes, 15 | SigningStargateClient, 16 | StargateClient, 17 | Tendermint34Client, 18 | buildFeeTable, 19 | GasPrice, 20 | } = require('@cosmjs/stargate'); 21 | const tx_1 = require('@cosmjs/stargate/build/codec/cosmos/tx/v1beta1/tx'); 22 | const tx_4 = require('@cosmjs/stargate/build/codec/cosmos/tx/v1beta1/tx'); 23 | 24 | const mnemonic = 'spice review cycle among deal estate main sport fold source face avocado'; 25 | 26 | async function main() { 27 | const registry = new Registry(defaultRegistryTypes); 28 | 29 | const rpcEndpoint = 'https://rpc.testnet.cosmos.network:443'; 30 | const serialized = 31 | '0a95010a92010a1c2f636f736d6f732e62616e6b2e763162657461312e4d736753656e6412720a2d636f736d6f733134686d3234653577657076357168356e79326c6335307632687537667939676b6c6364303777122d636f736d6f7331787639746b6c773764383273657a683968616135373377756667793539766d776536787865351a120a077570686f746f6e12073132333435363712690a500a460a1f2f636f736d6f732e63727970746f2e736563703235366b312e5075624b657912230a21025802f6b064ae8cd15053422905d304817c3418eb4e79f813e508127a8fc497c912040a020801180512150a0f0a077570686f746f6e1204323030301080f1041a4019b9bfc360c646413e5068c49b6f98ea7f47dbd76a443d1f1f0557ef3eb6acf779942a63bd21d29adc3ec0cce764232bcf92aafb5b2a92159c2cc99f33a310f5'; 32 | const tx = tx_4.TxRaw.decode(fromHex(serialized)); 33 | const authInfo = tx_4.AuthInfo.decode(tx.authInfoBytes); 34 | // const authInfo = tx_4.AuthInfo.decode(tx.authInfoBytes); 35 | console.log('tx', tx_4.TxRaw.toJSON(tx)); 36 | console.log('authInfo', JSON.stringify(tx_4.AuthInfo.toJSON(authInfo), null, 4)); 37 | console.log('body', registry.decodeTxBody(tx.bodyBytes)); 38 | 39 | console.log(toHex(fromBase64('CiECWAL2sGSujNFQU0IpBdMEgXw0GOtOefgT5QgSeo/El8k='))); 40 | let pub = decodePubkey({ 41 | typeUrl: '/cosmos.crypto.secp256k1.PubKey', 42 | value: fromBase64('CiECWAL2sGSujNFQU0IpBdMEgXw0GOtOefgT5QgSeo/El8k='), 43 | }); 44 | 45 | console.log(pub); 46 | console.log(toHex(fromBase64(pub.value))); 47 | // const address = pubkeyToAddress( 48 | // { 49 | // type: 'tendermint/PubKeySecp256k1', 50 | // value: 51 | // }, 52 | // 'cosmos' 53 | // ); 54 | return; 55 | } 56 | 57 | main().catch(console.error); 58 | -------------------------------------------------------------------------------- /examples/solana/squads-v4/account.ts: -------------------------------------------------------------------------------- 1 | import 'dotenv/config'; 2 | import bs58 from 'bs58'; 3 | import { clusterApiUrl, Connection, Keypair } from '@solana/web3.js'; 4 | import * as multisig from '@sqds/multisig'; 5 | 6 | const { Permissions, Permission } = multisig.types; 7 | 8 | // Cluster Connection 9 | var url = clusterApiUrl('devnet'); 10 | console.log('url : ', url); 11 | var connection = new Connection(url, 'confirmed'); 12 | 13 | var secretKey = process.env.SOL_SECRET_KEY; 14 | var aliceKey = process.env.SOL_ALICE_KEY; 15 | var bobKey = process.env.SOL_BOB_KEY; 16 | 17 | const payer = Keypair.fromSecretKey(bs58.decode(secretKey)); 18 | const alice = Keypair.fromSecretKey(bs58.decode(aliceKey)); 19 | const bob = Keypair.fromSecretKey(bs58.decode(bobKey)); 20 | const members = [payer, bob]; 21 | 22 | // Create a new multisig. 23 | async function main() { 24 | // Random Public Key that will be used to derive a multisig PDA 25 | const createKey = Keypair.generate(); 26 | 27 | // Creator should be a Keypair or a Wallet Adapter wallet 28 | const creator = payer; 29 | 30 | // Derive the multisig PDA 31 | const [multisigPda, multisigDump] = multisig.getMultisigPda({ 32 | // The createKey has to be a Public Key, see accounts reference for more info 33 | createKey: createKey.publicKey, 34 | }); 35 | 36 | const [programConfigPda] = multisig.getProgramConfigPda({}); 37 | 38 | const programConfig = await multisig.accounts.ProgramConfig.fromAccountAddress(connection, programConfigPda); 39 | 40 | const configTreasury = programConfig.treasury; 41 | 42 | const signature = await multisig.rpc.multisigCreateV2({ 43 | connection, 44 | // One time random Key 45 | createKey, 46 | // The creator & fee payer 47 | creator, 48 | multisigPda, 49 | configAuthority: null, 50 | timeLock: 0, 51 | // List of the members to add to the multisig 52 | members: [ 53 | { 54 | // Members Public Key 55 | key: creator.publicKey, 56 | // Members permissions inside the multisig 57 | permissions: Permissions.all(), 58 | }, 59 | { 60 | key: alice.publicKey, 61 | // Member can only add votes to proposed transactions 62 | permissions: Permissions.fromPermissions([Permission.Vote]), 63 | }, 64 | ], 65 | // This means that there needs to be 2 votes for a transaction proposal to be approved 66 | threshold: 2, 67 | rentCollector: null, 68 | treasury: configTreasury, 69 | sendOptions: { skipPreflight: true }, 70 | }); 71 | console.log('Multisig Pda: ', multisigPda.toBase58()); 72 | console.log('Multisig created: ', signature); 73 | } 74 | 75 | try { 76 | main(); 77 | } catch (e) { 78 | console.error(e); 79 | } 80 | -------------------------------------------------------------------------------- /website/docs/ripple/FAQ.md: -------------------------------------------------------------------------------- 1 | # Ripple 常见问题 2 | 3 | 基于你的实际代码实现,这里收集了 Ripple 开发中的常见问题和解答。 4 | 5 | ## 账户管理 6 | 7 | ### Q: 如何生成 Ripple 地址? 8 | A: 使用 `api.deriveKeypair(secret)` 派生密钥对,然后使用 `api.deriveAddress(publicKey)` 生成地址。 9 | 10 | ### Q: 经典地址和 X 地址有什么区别? 11 | A: 经典地址是传统格式,X 地址是新的格式,支持标签和网络标识。 12 | 13 | ### Q: 如何验证地址是否有效? 14 | A: 使用 `isValidAddress()` 函数验证地址格式和校验和。 15 | 16 | ### Q: 种子和私钥有什么区别? 17 | A: 种子是生成私钥的种子值,私钥是从种子派生的具体密钥。 18 | 19 | ## 交易处理 20 | 21 | ### Q: 如何创建和发送交易? 22 | A: 使用 `api.prepareTransaction()` 准备交易,`api.sign()` 签名,`api.submit()` 提交。 23 | 24 | ### Q: 交易费用是多少? 25 | A: 每笔交易通常需要 0.00001 XRP (10 drops) 作为基础费用。 26 | 27 | ### Q: 如何设置交易过期时间? 28 | A: 使用 `maxLedgerVersionOffset` 参数设置交易过期时间。 29 | 30 | ### Q: 可以离线创建交易吗? 31 | A: 可以,使用 `ripple-binary-codec` 进行离线交易处理。 32 | 33 | ## 多重签名 34 | 35 | ### Q: 多重签名支持多少个签名者? 36 | A: 最多支持 8 个签名者。 37 | 38 | ### Q: 如何设置多重签名权重? 39 | A: 在 `SignerEntry` 中设置 `SignerWeight` 字段。 40 | 41 | ### Q: 多重签名需要多少费用? 42 | A: 通常需要 10000 drops (0.01 XRP) 作为基础费用。 43 | 44 | ### Q: 可以修改多重签名配置吗? 45 | A: 可以,通过新的 `SignerListSet` 交易来更新配置。 46 | 47 | ## 网络和配置 48 | 49 | ### Q: 如何连接到不同的网络? 50 | A: 在创建 `RippleAPI` 实例时指定 `server` 参数。 51 | 52 | ### Q: 测试网和主网有什么区别? 53 | A: 测试网用于开发测试,主网用于生产环境。 54 | 55 | ### Q: 如何获取测试网 XRP? 56 | A: 使用 Ripple 测试网水龙头获取测试用 XRP。 57 | 58 | ### Q: 网络连接失败怎么办? 59 | A: 检查网络配置,尝试不同的服务器端点。 60 | 61 | ## 安全和最佳实践 62 | 63 | ### Q: 如何安全存储私钥? 64 | A: 使用安全的密钥管理系统,不要暴露给第三方。 65 | 66 | ### Q: 多重签名如何提高安全性? 67 | A: 通过分散签名权限,避免单点故障。 68 | 69 | ### Q: 如何处理交易失败? 70 | A: 检查错误代码,实现重试机制和错误处理。 71 | 72 | ### Q: 如何监控交易状态? 73 | A: 使用 `api.getTransaction()` 查询交易状态。 74 | 75 | ## 开发工具 76 | 77 | ### Q: 推荐使用哪些开发工具? 78 | A: `ripple-lib`、`ripple-address-codec`、`ripple-binary-codec` 等。 79 | 80 | ### Q: 如何调试交易问题? 81 | A: 使用日志记录,检查交易参数和网络状态。 82 | 83 | ### Q: 支持哪些编程语言? 84 | A: 主要支持 JavaScript/TypeScript,也有其他语言的绑定。 85 | 86 | ### Q: 如何获取最新的 API 文档? 87 | A: 访问 Ripple 官方开发者中心和 GitHub 仓库。 88 | 89 | ## 性能和优化 90 | 91 | ### Q: 如何优化交易处理速度? 92 | A: 合理设置交易参数,使用适当的网络连接。 93 | 94 | ### Q: 批量处理有什么建议? 95 | A: 使用适当的并发控制,避免过度请求。 96 | 97 | ### Q: 如何处理大量地址验证? 98 | A: 实现批量验证,使用缓存机制。 99 | 100 | ### Q: 网络延迟如何影响交易? 101 | A: 网络延迟会影响交易确认时间,建议使用就近的服务器。 102 | 103 | ## 错误处理 104 | 105 | ### Q: 常见的错误类型有哪些? 106 | A: 网络错误、参数错误、签名错误、余额不足等。 107 | 108 | ### Q: 如何实现错误重试? 109 | A: 实现指数退避重试机制,处理临时性错误。 110 | 111 | ### Q: 如何处理余额不足? 112 | A: 检查账户余额,确保有足够的 XRP 支付费用。 113 | 114 | ### Q: 交易被拒绝怎么办? 115 | A: 检查交易参数,确认账户状态和权限。 116 | 117 | ## 集成和部署 118 | 119 | ### Q: 如何集成到现有应用? 120 | A: 使用模块化设计,封装 Ripple 相关功能。 121 | 122 | ### Q: 生产环境需要注意什么? 123 | A: 使用主网配置,实现完整的错误处理和监控。 124 | 125 | ### Q: 如何监控应用状态? 126 | A: 实现健康检查、日志记录和性能监控。 127 | 128 | ### Q: 支持哪些部署方式? 129 | A: 支持容器化部署、云服务部署等多种方式。 130 | -------------------------------------------------------------------------------- /examples/ethereum/tx/erc20.js: -------------------------------------------------------------------------------- 1 | require('dotenv').config(); 2 | const { Transaction } = require('@ethereumjs/tx'); 3 | const { default: Common } = require('@ethereumjs/common'); 4 | const { bufferToHex, stripHexPrefix } = require('ethereumjs-util'); 5 | const { default: BigNumber } = require('bignumber.js'); 6 | 7 | const { PRIVATE_KEY } = process.env; 8 | 9 | function sendTx(web3, data) { 10 | return new Promise((resolve, reject) => { 11 | web3.eth 12 | .sendSignedTransaction(data) 13 | .once('transactionHash', (hash) => { 14 | resolve(hash); 15 | }) 16 | .on('error', function (error) { 17 | reject(error); 18 | }); 19 | }); 20 | } 21 | 22 | const Web3 = require('web3'); 23 | 24 | const provider = 'https://kovan.infura.io/v3/de9290b603fc4609a6f0a65e23e8c7d3'; 25 | const web3 = new Web3(provider); 26 | 27 | async function main() { 28 | const from = '0xd73d9AA55ABBd6CFbeD3e9Ad7f8Be2f6D83C70dC'; 29 | const to = '0x370BA1dc25C07d0C77Ba9b83fcc75Fcc2a0aC243'; 30 | const tokenAddress = '0x5abe286f5ea6132b157cfd728834d493cbd43314'; 31 | const quantity = new BigNumber(1000).shiftedBy(18).toFixed(); 32 | const common = new Common({ chain: 'kovan' }); 33 | const txOptions = { common }; 34 | 35 | const raw = '0000000000000000000000000000000000000000000000000000000000000000'; 36 | const amount = new BigNumber(quantity).toString(16); 37 | const input = 38 | '0xa9059cbb000000000000000000000000' + // token transfer method 39 | stripHexPrefix(to) + // to address 40 | raw.substring(0, raw.length - amount.length) + // placeholder 41 | amount; // amount 42 | 43 | const nonce = await web3.eth.getTransactionCount(from); 44 | const gasPrice = await web3.eth.getGasPrice(); 45 | console.log('gasPrice', gasPrice); 46 | const estimateGas = await web3.eth.estimateGas({ 47 | from, 48 | to: tokenAddress, 49 | data: input, 50 | gasPrice, 51 | nonce, 52 | value: '0x00', 53 | }); 54 | console.log('estimateGas', estimateGas); 55 | const gasLimit = new BigNumber(estimateGas).toString(); 56 | 57 | const txData = { 58 | from, 59 | to: tokenAddress, 60 | data: input, 61 | value: '0x00', 62 | nonce: nonce ? '0x' + new BigNumber(nonce).toString(16) : '0x', 63 | gasPrice: '0x' + new BigNumber(gasPrice).toString(16), 64 | gasLimit: '0x' + new BigNumber(gasLimit).toString(16), 65 | }; 66 | const tx = Transaction.fromTxData(txData, txOptions); 67 | const privatekey = Buffer.from(PRIVATE_KEY, 'hex'); 68 | 69 | const signedTx = tx.sign(privatekey); 70 | const serializedTx = signedTx.serialize(); 71 | 72 | console.log('bufferToHex(serializedTx)', bufferToHex(serializedTx)); 73 | const hash = await sendTx(web3, bufferToHex(serializedTx)); 74 | console.log('hash', hash); 75 | } 76 | 77 | main().then().catch(console.error); 78 | -------------------------------------------------------------------------------- /examples/bitcoin/classify.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, test, expect } from 'vitest'; 2 | 3 | import { types, p2sh, p2pk, p2pkh, p2wsh, p2wpkh, multisig } from './classify'; 4 | import { fromASM } from './script'; 5 | import { valid } from './__mocks__/classify.json'; 6 | 7 | describe('Bitcoin classify', () => { 8 | describe('valid', () => { 9 | describe('p2sh', () => { 10 | const items = valid.filter((item) => item.type === types.P2SH); 11 | test.each(items)('classifies $output is $type', ({ output, outputHex }) => { 12 | const hex = fromASM(output); 13 | expect(outputHex).toEqual(hex.toString('hex')); 14 | 15 | const matched = p2sh(hex); 16 | expect(matched).toEqual(true); 17 | }); 18 | }); 19 | 20 | describe('p2pk', () => { 21 | const items = valid.filter((item) => item.type === types.P2PK); 22 | test.each(items)('classifies $output is $type', ({ output, outputHex }) => { 23 | const hex = fromASM(output); 24 | expect(outputHex).toEqual(hex.toString('hex')); 25 | 26 | const matched = p2pk(hex); 27 | expect(matched).toEqual(true); 28 | }); 29 | }); 30 | 31 | describe('p2pkh', () => { 32 | const items = valid.filter((item) => item.type === types.P2PKH); 33 | test.each(items)('classifies $output is $type', ({ output, outputHex }) => { 34 | const hex = fromASM(output); 35 | expect(outputHex).toEqual(hex.toString('hex')); 36 | 37 | const matched = p2pkh(hex); 38 | expect(matched).toEqual(true); 39 | }); 40 | }); 41 | 42 | describe('p2wsh', () => { 43 | const items = valid.filter((item) => item.type === types.P2WSH); 44 | test.each(items)('classifies $output is $type', ({ output, outputHex }) => { 45 | const hex = fromASM(output); 46 | expect(outputHex).toEqual(hex.toString('hex')); 47 | 48 | const matched = p2wsh(hex); 49 | expect(matched).toEqual(true); 50 | }); 51 | }); 52 | 53 | describe('p2wpkh', () => { 54 | const items = valid.filter((item) => item.type === types.P2WPKH); 55 | test.each(items)('classifies $output is $type', ({ output, outputHex }) => { 56 | const hex = fromASM(output); 57 | expect(outputHex).toEqual(hex.toString('hex')); 58 | 59 | const matched = p2wpkh(hex); 60 | expect(matched).toEqual(true); 61 | }); 62 | }); 63 | 64 | describe('multisig', () => { 65 | const items = valid.filter((item) => item.type === types.P2MS); 66 | test.each(items)('classifies $output is $type', ({ output, outputHex }) => { 67 | const hex = fromASM(output); 68 | expect(outputHex).toEqual(hex.toString('hex')); 69 | 70 | const matched = multisig(hex); 71 | expect(matched).toEqual(true); 72 | }); 73 | }); 74 | }); 75 | }); 76 | -------------------------------------------------------------------------------- /examples/aptos/account.ts: -------------------------------------------------------------------------------- 1 | import { AptosClient, AptosAccount, FaucetClient, HexString, } from "aptos"; 2 | import assert from 'assert'; 3 | import nacl from 'tweetnacl'; 4 | import { sha3_256 } from '@noble/hashes/sha3'; 5 | 6 | function pubKeyToAddress(publicKey: Uint8Array) { 7 | const hash = sha3_256.create(); 8 | hash.update(publicKey); 9 | hash.update("\0"); 10 | return HexString.fromUint8Array(hash.digest()); 11 | } 12 | 13 | async function main() { 14 | const signingMessage = new HexString('0x4cd1').toUint8Array(); 15 | const privateKeyHex = '0x4cd1fff838717a1a175df49a502107f0377476a79d256ecd696121f72226a61c'; 16 | const aptosCoin = '0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>'; 17 | const privateKeyHexStr = new HexString(privateKeyHex); 18 | const NODE_URL = 'https://fullnode.devnet.aptoslabs.com'; 19 | const FAUCET_URL = 'https://faucet.devnet.aptoslabs.com'; 20 | 21 | const account = new AptosAccount(privateKeyHexStr.toUint8Array()); 22 | const address = account.address(); 23 | // public key -> address 24 | { 25 | const pubKeyHexStr = HexString.ensure('0xacdf5b6a88282858e157589119ea965cdeedab5f062ee3fb252b65cb15f7cbe9'); 26 | const address = pubKeyToAddress(pubKeyHexStr.toUint8Array()); 27 | assert.strictEqual(address.hex(), '0xdd7862a1d347806c9470ba6e4d13b91b60ba5539a00065090ce8bbc24c4dd37a') 28 | } 29 | // fund account 30 | { 31 | const faucetClient = new FaucetClient(NODE_URL, FAUCET_URL, null); 32 | await faucetClient.fundAccount('0x689b4250f7d1c3784c5fb947fc9f15fd8e1842b4425976d8a44e4221150b1f79', 100_000_000); 33 | } 34 | 35 | // account 36 | { 37 | const privateKeyObject = account.toPrivateKeyObject(); 38 | console.log('address : ', address); 39 | console.log('privateKeyObject : ', privateKeyObject); 40 | } 41 | 42 | // resources 43 | { 44 | const client = new AptosClient(NODE_URL); 45 | const resources = await client.getAccountResources(address); 46 | const accountResource = resources.find((r) => r.type === aptosCoin); 47 | console.log('resources : ', resources); 48 | console.log('accountResource : ', accountResource); 49 | console.log(`account coins : ${accountResource?.data?.coin?.value}. Should be 100_000_000!`); 50 | } 51 | 52 | // sign 53 | { 54 | const signedMsg = nacl.sign(signingMessage, account.signingKey.secretKey); 55 | console.log('signedMsg : ', HexString.fromUint8Array(signedMsg).hex()); 56 | } 57 | { 58 | const pubKeyHexStr = HexString.ensure('0xacdf5b6a88282858e157589119ea965cdeedab5f062ee3fb252b65cb15f7cbe9'); 59 | const address = pubKeyToAddress(pubKeyHexStr.toUint8Array()); 60 | console.log('address : ', address.hex()); 61 | } 62 | // faucet 63 | { 64 | const faucetClient = new FaucetClient(NODE_URL, FAUCET_URL, null); 65 | await faucetClient.fundAccount('0xf7201ffdfac8f6d3b2ea5c98b4932b3c4b7d3c3565e734288a374c9f0616333b', 100_000_000); 66 | } 67 | } 68 | 69 | main().catch(console.error); 70 | -------------------------------------------------------------------------------- /website/blog/tags.yml: -------------------------------------------------------------------------------- 1 | facebook: 2 | label: Facebook 3 | permalink: /facebook 4 | description: Facebook tag description 5 | 6 | bitcoin: 7 | label: bitcoin 8 | permalink: /bitcoin 9 | description: Bitcoin tag description 10 | 11 | bech32: 12 | label: bech32 13 | permalink: /bech32 14 | description: Bech32 tag description 15 | 16 | ethereum: 17 | label: ethereum 18 | permalink: /ethereum 19 | description: Ethereum blockchain development and smart contracts 20 | 21 | eip1559: 22 | label: eip1559 23 | permalink: /eip1559 24 | description: EIP-1559 transaction format and gas fee optimization 25 | 26 | multisig: 27 | label: multisig 28 | permalink: /multisig 29 | description: Multi-signature wallets and Gnosis Safe integration 30 | 31 | script: 32 | label: script 33 | permalink: /script 34 | description: Bitcoin script programming language and operations 35 | 36 | base58: 37 | label: base58 38 | permalink: /base58 39 | description: Base58 encoding for Bitcoin addresses 40 | 41 | psbt: 42 | label: psbt 43 | permalink: /psbt 44 | description: Partially Signed Bitcoin Transactions 45 | 46 | utxo: 47 | label: utxo 48 | permalink: /utxo 49 | description: Unspent Transaction Output model 50 | 51 | docusaurus: 52 | label: Docusaurus 53 | permalink: /docusaurus 54 | description: Docusaurus tag description 55 | 56 | # 新增的标签定义 57 | transaction: 58 | label: transaction 59 | permalink: /transaction 60 | description: Bitcoin and blockchain transaction types and operations 61 | 62 | p2pkh: 63 | label: P2PKH 64 | permalink: /p2pkh 65 | description: Pay-to-Public-Key-Hash transaction type 66 | 67 | p2sh: 68 | label: P2SH 69 | permalink: /p2sh 70 | description: Pay-to-Script-Hash transaction type 71 | 72 | segwit: 73 | label: SegWit 74 | permalink: /segwit 75 | description: Segregated Witness protocol implementation 76 | 77 | signature: 78 | label: signature 79 | permalink: /signature 80 | description: Cryptographic signature operations 81 | 82 | bitcoinjs-lib: 83 | label: bitcoinjs-lib 84 | permalink: /bitcoinjs-lib 85 | description: Bitcoin JavaScript library for transaction operations 86 | 87 | blockchain: 88 | label: blockchain 89 | permalink: /blockchain 90 | description: Blockchain technology and development 91 | 92 | development: 93 | label: development 94 | permalink: /development 95 | description: Blockchain and cryptocurrency development 96 | 97 | address: 98 | label: address 99 | permalink: /address 100 | description: Cryptocurrency address generation and validation 101 | 102 | cryptography: 103 | label: cryptography 104 | permalink: /cryptography 105 | description: Cryptographic algorithms and security 106 | 107 | account: 108 | label: account 109 | permalink: /account 110 | description: Blockchain account management and operations 111 | -------------------------------------------------------------------------------- /website/src/components/ui/pagination.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { ChevronLeft, ChevronRight, MoreHorizontal } from 'lucide-react'; 3 | 4 | import { cn } from '../../lib/utils'; 5 | import { ButtonProps, buttonVariants } from '../../components/ui/button'; 6 | 7 | const Pagination = ({ className, ...props }: React.ComponentProps<'nav'>) => ( 8 |