├── .gitignore ├── README.md ├── aptos_vs_sui.md ├── aptos_vs_sui_en.md ├── aptosname-transfer ├── Move.toml ├── package-lock.json ├── package.json ├── sources │ └── transfer.move └── src │ └── get_token.js ├── docs ├── aptos_whitepaper_by_moveworld.pdf └── sui_whitepaper_by_moveworld.pdf ├── hash_type_and_key ├── Cargo.lock ├── Cargo.toml ├── README.md └── src │ └── main.rs ├── multisig-transaction ├── README.md ├── package.json ├── src │ ├── multisign_commit.js │ ├── multisign_create.js │ ├── multisign_register.js │ └── multisign_transfer.js └── yarn.lock ├── mycoin ├── Move.toml ├── README.md └── sources │ └── coins.move ├── sui-scripts ├── package.json ├── src │ ├── devInspectMoveCall.js │ ├── devInspectTransaction.js │ ├── dryRunTransaction.js │ ├── executeTransaction.js │ └── get_objects.js └── yarn.lock └── sui-vector ├── Move.toml ├── README.md ├── call.ts ├── package.json ├── sources └── vector.move └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | *.aptos/ 2 | */build/ 3 | */node_modules/ 4 | *target/ 5 | /sui-vector/.env 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # move 开发者资料 3 | 4 | 0. 项目白皮书 5 | - [aptos白皮书英文原版](https://aptos.dev/assets/files/2022.08.11.10.00.aptos_whitepaper-47099b4b907b432f81fc0effd34f3b6a.pdf) 6 | - [aptos白皮书中文版](./docs/aptos_whitepaper_by_moveworld.pdf) 7 | - [sui白皮书英文原版](https://github.com/MystenLabs/sui/blob/main/doc/paper/sui.pdf) 8 | - [sui白皮书中文版](./docs/sui_whitepaper_by_moveworld.pdf) 9 | 10 | 1. ****Aptos**** 11 | ```txt 12 | Aptos 官网 [https://aptoslabs.com/](https://aptoslabs.com/) 13 | Aptos 代码 [https://github.com/aptos-labs/aptos-core](https://github.com/aptos-labs/aptos-core) 14 | Aptos 官方钱包 [https://aptos.dev/guides/building-wallet-extension/](https://aptos.dev/guides/building-wallet-extension/) 15 | Aptos 第三方钱包 [https://martianwallet.xyz/](https://martianwallet.xyz/) 16 | Aptos 区块浏览器 [https://explorer.devnet.aptos.dev/](https://explorer.devnet.aptos.dev/) 17 | Aptos 官方文档 [https://aptos.dev/](https://aptos.dev/) 18 | Aptos 生态 [https://aptos.super.site/](https://aptos.super.site/) 19 | 20 | 普通转账 21 | 1. 搭建local测试网 22 | 方式1:(需要编译aptos) 23 | aptos node run-local-testnet --force-restart --with-faucet 24 | 25 | 方式2:(需要编译aptos-node, aptos-faucet) 26 | https://aptos.dev/nodes/run-a-local-testnet 27 | 28 | CARGO_NET_GIT_FETCH_WITH_CLI=true aptos-node --test --test-dir test 29 | 30 | 水龙头 31 | aptos-faucet --chain-id TESTING --mint-key-file-path "./test/mint.key" --address 0.0.0.0 --port 8000 --server-url http://127.0.0.1:8080 32 | 33 | 领取localnet测试币 34 | curl --location --request POST 'http://127.0.0.1:8000/mint?amount=10000000&address=a24881e004fdbc5550932bb2879129351c21432f21f32d94bf11603bebd9f5c0' 35 | 领取aptos devnet测试币 36 | curl --location --request POST 'https://faucet.devnet.aptoslabs.com/mint?amount=1000&address=a24881e004fdbc5550932bb2879129351c21432f21f32d94bf11603bebd9f5c0' 37 | 38 | 2. 区块浏览器 39 | https://explorer.devnet.aptos.dev/?network=local 40 | 41 | 3. 安装aptos插件钱包: https://petra.app/ 42 | 43 | 钱包连接local测试网(关闭代理, 让钱包连接Localhost) 44 | 45 | Petra 默认调用 http://localhost:80 领取水龙头测试币 46 | 所以需要本地配置端口转发(80 -> 8000), 47 | 48 | sudo socat TCP4-LISTEN:80,reuseaddr,fork TCP4:127.0.0.1:8000 49 | 50 | 如果不用插件钱包,可以编译aptos,可用这个命令行工具转账 51 | 注意: 52 | (1) pubkey不等于address(aptos init的时候需要填写私钥,如果没有注册,会打印出account 地址) 53 | (2) transfer 相关的from和to都必须在链上存在才能转账成功 54 | aptos key generate --output-file testkey 55 | 56 | aptos account create --account \ 57 | 0xb00939ac2e339fca870ee96826e75f851ea74d65039f850f980906744f7a7cdd \ 58 | --url http://127.0.0.1:8080 --faucet-url http://127.0.0.1:8000 \ 59 | --use-faucet 60 | aptos account list --account \ 61 | 0xb00939ac2e339fca870ee96826e75f851ea74d65039f850f980906744f7a7cdd \ 62 | --url http://127.0.0.1:8080 63 | 64 | aptos account create --account \ 65 | 0x96ea2aac87bd650548a1bf6d740fff4b86e7a82d6daa2b9673d026bfe363a32d \ 66 | --url http://127.0.0.1:8080 --faucet-url http://127.0.0.1:8000 \ 67 | --use-faucet 68 | 69 | aptos account list --account \ 70 | 0x96ea2aac87bd650548a1bf6d740fff4b86e7a82d6daa2b9673d026bfe363a32d \ 71 | --url http://127.0.0.1:8080 72 | 73 | ./aptos account transfer --account \ 74 | 0x96ea2aac87bd650548a1bf6d740fff4b86e7a82d6daa2b9673d026bfe363a32d \ 75 | --amount 1000 --private-key-file testkey \ 76 | --url http://127.0.0.1:8080 77 | 78 | 4. 通过插件钱包进行普通转账 79 | 80 | 合约开发 81 | 5. 编译aptos 82 | cd crates/aptos && cargo build --release 83 | 6. aptos move提供了move合约开发的系列工具,且内置使用aptos-framework( 84 | aptos自带的move合约库,以及move自带的,这些基础的move合约开箱即用) 85 | https://aptos.dev/cli-tools/aptos-cli-tool/use-aptos-cli/#move-examples 86 | 87 | (1) mkdir move-example && cd move-example 88 | (2) aptos move init --name basecoin --named-addresses basecoin=0xCAFE 89 | 本地开发,修改Move.toml,指定本地依赖 AptosFramework 90 | AptosFramework = { local = "../../aptos-move/framework/aptos-framework" } 91 | (3) 编写 basecoin 合约内容 92 | (4) aptos move compile 93 | (5) aptos move test 94 | (6) aptos move publish \ 95 | --named-addresses basecoin=0xb00939ac2e339fca870ee96826e75f851ea74d65039f850f980906744f7a7cdd \ 96 | --private-key-file testkey 97 | --url http://127.0.0.1:8080 98 | (7) aptos move run \ 99 | --function-id 0xb00939ac2e339fca870ee96826e75f851ea74d65039f850f980906744f7a7cdd::BasicCoin::mint \ 100 | --private-key-file testkey \ 101 | --url http://127.0.0.1:8080 \ 102 | --args u64:5555 103 | (8) apt init 104 | 将url和私钥配置到.apt目录,上面的命令就可以不用指定url和私钥了 105 | 106 | 合约升级 107 | 7. aptos move publish --upgrade-policy 108 | `arbitrary`, `compatible`, `immutable` 对应 0, 1,2 109 | 0 不做任何检查,强制替换code, 110 | 1 做兼容性检查(同样的public 函数,不能改变已有Resource的内存布局) 111 | 2 禁止升级 112 | 每次publish的时候会比较链上的policy和此次publish的policy(默认是1), 113 | 只有此次的policy小于链上的policy时才允许合约升级 114 | ``` 115 | 116 | 2. ****Sui**** 117 | ```txt 118 | Sui 官网: https://sui.io/# 119 | Sui 代码: https://github.com/MystenLabs/sui 120 | Sui 官方钱包(浏览器插件): https://docs.sui.io/devnet/explore/wallet-browser 121 | Sui 浏览器: https://explorer.devnet.sui.io/ 122 | Sui 官方文档: https://docs.sui.io/learn 123 | 124 | 1. 源码编译 125 | git clone https://github.com/MystenLabs/sui.git 126 | git checkout devnet-0.9.0 127 | cargo build --release 128 | 129 | 得 sui,sui-node,sui-faucet,sui-test-validator 130 | 131 | 2. 本地测试网搭建1(快速启动,数据不复用) 132 | sui-test-validator会在临时目录下创建4个validators+1个fullnode的local测试网(faucet账户1000个gas object,即 100000000000) 133 | (1) 执行命令, 起测试网 134 | $ sui-test-validator 135 | Fullnode RPC URL: http://127.0.0.1:9000 136 | Fullnode Websocket URL: 127.0.0.1:9001 137 | Gateway RPC URL: http://127.0.0.1:5001 138 | Faucet URL: http://127.0.0.1:9123 139 | 140 | (2) 检查代理, 浏览器打开 https://explorer.devnet.sui.io/, 选择Local 141 | 142 | (3) 执行命令, 领测试币 143 | $ curl -H "Content-Type: application/json" -X POST -d '{"FixedAmountRequest":{"recipient":"0x017614990a894ad7c26f5bd174ea9c8095b06242"}}' "http://127.0.0.1:9123/gas" 144 | {"ok":true} 145 | 146 | 3. 本地测试网搭建2(重启后数据可复用) 147 | 默认目录(linux): ~/.sui/ 148 | (1) 生成genesis及配置文件(4个validators+1个fullnode) 149 | $ sui genesis 150 | 2022-09-14T06:01:24.030408Z INFO sui_config::genesis_config: Creating accounts and gas objects... 151 | 2022-09-14T06:01:24.069524Z INFO sui::sui_commands: Network genesis completed. 152 | 2022-09-14T06:01:24.070775Z INFO sui::sui_commands: Network config file is stored in "/home/chain/.sui/sui_config/network.yaml". 153 | 2022-09-14T06:01:24.070783Z INFO sui::sui_commands: Client keystore is stored in "/home/chain/.sui/sui_config/sui.keystore". 154 | 2022-09-14T06:01:24.070872Z INFO sui::sui_commands: Gateway config file is stored in "/home/chain/.sui/sui_config/gateway.yaml". 155 | 2022-09-14T06:01:24.070970Z INFO sui::sui_commands: Client config file is stored in "/home/chain/.sui/sui_config/client.yaml". 156 | 157 | (2) validators 组网 158 | $ sui start 159 | 160 | (3) 启动fullnode(http和websocket服务) 161 | $ sui-node --config-path ~/.sui/sui_config/fullnode.yaml 162 | 163 | (4) 检查代理, 浏览器打开 https://explorer.devnet.sui.io/, 选择Local 164 | 165 | (5) 检查代理, 启动水龙头 166 | $ sui-faucet 167 | 2022-09-14T06:09:15.489118Z INFO sui_faucet: Max concurrency: 30. 168 | 2022-09-14T06:09:15.489631Z INFO sui_faucet: Initialize wallet from config path: "/home/chain/.sui/sui_config/client.yaml" 169 | 2022-09-14T06:09:15.555282Z INFO sui_storage::lock_service: LockService command processing loop started 170 | 2022-09-14T06:09:15.555280Z INFO sui_storage::lock_service: LockService queries processing loop started 171 | 2022-09-14T06:09:15.577705Z INFO sui_faucet: Starting Prometheus HTTP endpoint at 0.0.0.0:9184 172 | 2022-09-14T06:09:15.579142Z INFO sui_faucet::faucet::simple_faucet: SimpleFaucet::new with active address: 0x07eab5bb4dbdffd5d2c12c6431da8609ae3b5dd8 173 | 2022-09-14T06:09:15.600278Z INFO sui_faucet: listening on 127.0.0.1:5003 174 | 175 | (6) 检查水龙头服务 176 | $ curl http://127.0.0.1:5003 177 | OK 178 | 179 | (7) 执行命令, 领测试币 180 | $ curl -H "Content-Type: application/json" \ 181 | -X POST \ 182 | -d '{"FixedAmountRequest":{"recipient":"0x017614990a894ad7c26f5bd174ea9c8095b06242"}}' \ 183 | "http://127.0.0.1:5003/gas" 184 | 185 | (8) 多个网络环境切换 186 | sui client new-env --alias testnet --rpc https://fullnode.testnet.sui.io:443 187 | sui client new-env --alias local --rpc http://127.0.0.1:9000 188 | sui client switch --env testnet 189 | 190 | 4. 普通转账 191 | (1) 查看默认账户(用于签名交易) 192 | $ sui client active-address 193 | 0x07eab5bb4dbdffd5d2c12c6431da8609ae3b5dd8 194 | 195 | (2) 查看当前客户端下的所有账户 196 | $ sui client addresses 197 | Showing 5 results. 198 | 0x07eab5bb4dbdffd5d2c12c6431da8609ae3b5dd8 199 | 0x143eaa9b239382f6a5c360c0c407571183efea5a 200 | 0x62427915aba4c593e4d6092ebe8740f3de73d413 201 | 0x7ab69f783fdd9f3f1021cb6249bd9b373be950e3 202 | 0xc2bfdd8e835d9419414eb20d6d85da54b6d7ef83 203 | 204 | (3) 查看默认账户所有的objects 205 | $ sui client objects 206 | Object ID | Version | Digest | Owner Type | Object Type 207 | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- 208 | 0x25500da23617b95f5cc40c6695f12ac97c29b9fa | 1 | sr4wny/27v+VuHZhsTyv5UQCuXa33MijQBuCJTi4UVg= | AddressOwner | 0x2::coin::Coin<0x2::sui::SUI> 209 | 0x619d9baa1fc679736a16298f433057874ef1c9cb | 1 | oG7nB0qgghNjvKQS2iRj/2ffXFcM4TzqgtyFNP8cFmA= | AddressOwner | 0x2::coin::Coin<0x2::sui::SUI> 210 | 0x86169c6f94351861f4203d9bec4074483ece743b | 1 | NagZV0AvyYeBM5T4+Qqewu9dhrOsWoI6N/F1s3hshfU= | AddressOwner | 0x2::coin::Coin<0x2::sui::SUI> 211 | 0x9f9a9bce97390e0cc2580b337f6f25c77b031668 | 1 | sD/Cpl/DVpETNNQW8iY+dfiEC4UzBbQrx0X5bffF7t0= | AddressOwner | 0x2::coin::Coin<0x2::sui::SUI> 212 | 0xa98efc17c852db6970541e31409a1c9e83d26f02 | 1 | n9HhBXkhhGytAGiugM9QPxDb/nAqoMUc/lFSjiGixCM= | AddressOwner | 0x2::coin::Coin<0x2::sui::SUI> 213 | Showing 5 results. 214 | 215 | (4) 查看指定object 216 | $ sui client object --id 0x25500da23617b95f5cc40c6695f12ac97c29b9fa 217 | ----- Move Object (0x25500da23617b95f5cc40c6695f12ac97c29b9fa[1]) ----- 218 | Owner: Account Address ( 0x07eab5bb4dbdffd5d2c12c6431da8609ae3b5dd8 ) 219 | Version: 1 220 | Storage Rebate: 16 221 | Previous Transaction: Avc/mpGqjUKSspkklOHI7d0xTkFdx36e2hRowMPrP+w= 222 | ----- Data ----- 223 | type: 0x2::coin::Coin<0x2::sui::SUI> 224 | balance: 99949907 225 | id: 0x25500da23617b95f5cc40c6695f12ac97c29b9fa 226 | 227 | (5) 查看指定账户余额 228 | $ sui client gas --address 0x07eab5bb4dbdffd5d2c12c6431da8609ae3b5dd8 229 | Object ID | Gas Value 230 | ---------------------------------------------------------------------- 231 | 0x25500da23617b95f5cc40c6695f12ac97c29b9fa | 99949746 232 | 0x619d9baa1fc679736a16298f433057874ef1c9cb | 99949907 233 | 0x86169c6f94351861f4203d9bec4074483ece743b | 99949907 234 | 0x9f9a9bce97390e0cc2580b337f6f25c77b031668 | 99949907 235 | 0xa98efc17c852db6970541e31409a1c9e83d26f02 | 99949907 236 | 237 | (6) 转 500 sui 到 0x017614990a894ad7c26f5bd174ea9c8095b06242 238 | $ sui client transfer-sui \ 239 | --amount 100 \ 240 | --to 0x017614990a894ad7c26f5bd174ea9c8095b06242 \ 241 | --sui-coin-object-id 0x25500da23617b95f5cc40c6695f12ac97c29b9fa \ 242 | --gas-budget 10000 243 | 244 | ----- Certificate ---- 245 | Transaction Hash: 9WNSiDt4kHvHJbuwcYPgA5qMXpLzFRadirDtXpuMaEU= 246 | Transaction Signature: AA==@o1IqHwSDateWAaxquRdrk0nlSrn0LszM9YTTV4HAn0Urlo2mOK07ppSCXEWHutsZQffMdzkC2Ri8vfwr4FwxBA==@DRaRxLuGWh9Y7gU0bePmmBNaSF+xXrZita1rfGgdZa0= 247 | Signed Authorities Bitmap: RoaringBitmap<[0, 1, 2]> 248 | Transaction Kind : Transfer SUI 249 | Recipient : 0x017614990a894ad7c26f5bd174ea9c8095b06242 250 | Amount: 100 251 | 252 | ----- Transaction Effects ---- 253 | Status : Success 254 | Created Objects: 255 | - ID: 0x7cbeb294db017cc6c1f95e1151738642640fa36e , Owner: Account Address ( 0x017614990a894ad7c26f5bd174ea9c8095b06242 ) 256 | Mutated Objects: 257 | - ID: 0x25500da23617b95f5cc40c6695f12ac97c29b9fa , Owner: Account Address ( 0x07eab5bb4dbdffd5d2c12c6431da8609ae3b5dd8 ) 258 | 259 | 5. sui的合并与拆解 260 | (1) merge-coin 261 | 合并前 262 | $ sui client gas --address 0x07eab5bb4dbdffd5d2c12c6431da8609ae3b5dd8 263 | Object ID | Gas Value 264 | ---------------------------------------------------------------------- 265 | 0x25500da23617b95f5cc40c6695f12ac97c29b9fa | 99949746 266 | 0x619d9baa1fc679736a16298f433057874ef1c9cb | 99949907 267 | 0x86169c6f94351861f4203d9bec4074483ece743b | 99949907 268 | 0x9f9a9bce97390e0cc2580b337f6f25c77b031668 | 99949907 269 | 0xa98efc17c852db6970541e31409a1c9e83d26f02 | 99949907 270 | 271 | 将 0xa98efc17c852db6970541e31409a1c9e83d26f02 合并到 0x9f9a9bce97390e0cc2580b337f6f25c77b031668 272 | $ sui client merge-coin \ 273 | --primary-coin 0x9f9a9bce97390e0cc2580b337f6f25c77b031668 \ 274 | --coin-to-merge 0xa98efc17c852db6970541e31409a1c9e83d26f02 \ 275 | --gas-budget 1000 276 | ----- Certificate ---- 277 | Transaction Hash: tolTzRhi+D0i1OxW7Av/lAAj0AlSvEwJTHcThXwiy9E= 278 | Transaction Signature: AA==@yKbytoEFIkG4hgD69w4B/x0OpOdeFuwTYwMNmLYWC3ccC2HHqj10d3EQJhUddjiXOSA4DTrvcDXg+RbQfi5jCg==@DRaRxLuGWh9Y7gU0bePmmBNaSF+xXrZita1rfGgdZa0= 279 | Signed Authorities Bitmap: RoaringBitmap<[0, 2, 3]> 280 | Transaction Kind : Call 281 | Package ID : 0x2 282 | Module : coin 283 | Function : join 284 | Arguments : ["0x9f9a9bce97390e0cc2580b337f6f25c77b031668", "0xa98efc17c852db6970541e31409a1c9e83d26f02"] 285 | Type Arguments : ["0x2::sui::SUI"] 286 | ----- Transaction Effects ---- 287 | Status : Success 288 | Mutated Objects: 289 | - ID: 0x25500da23617b95f5cc40c6695f12ac97c29b9fa , Owner: Account Address ( 0x07eab5bb4dbdffd5d2c12c6431da8609ae3b5dd8 ) 290 | - ID: 0x9f9a9bce97390e0cc2580b337f6f25c77b031668 , Owner: Account Address ( 0x07eab5bb4dbdffd5d2c12c6431da8609ae3b5dd8 ) 291 | Deleted Objects: 292 | - ID: 0xa98efc17c852db6970541e31409a1c9e83d26f02 293 | ----- Merge Coin Results ---- 294 | Updated Coin : Coin { id: 0x9f9a9bce97390e0cc2580b337f6f25c77b031668, value: 199899814 } 295 | Updated Gas : Coin { id: 0x25500da23617b95f5cc40c6695f12ac97c29b9fa, value: 99949299 } 296 | 297 | 合并后 298 | $ sui client gas --address 0x07eab5bb4dbdffd5d2c12c6431da8609ae3b5dd8 299 | Object ID | Gas Value 300 | ---------------------------------------------------------------------- 301 | 0x25500da23617b95f5cc40c6695f12ac97c29b9fa | 99949299 302 | 0x619d9baa1fc679736a16298f433057874ef1c9cb | 99949907 303 | 0x86169c6f94351861f4203d9bec4074483ece743b | 99949907 304 | 0x9f9a9bce97390e0cc2580b337f6f25c77b031668 | 199899814 305 | 306 | (2) split-coin 307 | 2等分一个coin object 308 | $ sui client split-coin \ 309 | --coin-id 0x9f9a9bce97390e0cc2580b337f6f25c77b031668 \ 310 | --count 2 \ 311 | --gas-budget 1000 312 | ----- Certificate ---- 313 | Transaction Hash: AIxZ7PdmmIe1xrDmSj9mVfnd+CH3bowZhNQemCDNX80= 314 | Transaction Signature: AA==@MSJHoyxe5TQTbcc4F3/aqXEMzczVEE5gyvHmPDc6+md9sBbz0aX4RnZl7B67Yhj8/fgXsL/ZdsubuidO1w5qBA==@DRaRxLuGWh9Y7gU0bePmmBNaSF+xXrZita1rfGgdZa0= 315 | Signed Authorities Bitmap: RoaringBitmap<[0, 2, 3]> 316 | Transaction Kind : Call 317 | Package ID : 0x2 318 | Module : coin 319 | Function : split_n 320 | Arguments : ["0x9f9a9bce97390e0cc2580b337f6f25c77b031668", 2] 321 | Type Arguments : ["0x2::sui::SUI"] 322 | ----- Transaction Effects ---- 323 | Status : Success 324 | Created Objects: 325 | - ID: 0xcce677fe40fb33fb5825498b2d379985c4f080c4 , Owner: Account Address ( 0x07eab5bb4dbdffd5d2c12c6431da8609ae3b5dd8 ) 326 | Mutated Objects: 327 | - ID: 0x25500da23617b95f5cc40c6695f12ac97c29b9fa , Owner: Account Address ( 0x07eab5bb4dbdffd5d2c12c6431da8609ae3b5dd8 ) 328 | - ID: 0x9f9a9bce97390e0cc2580b337f6f25c77b031668 , Owner: Account Address ( 0x07eab5bb4dbdffd5d2c12c6431da8609ae3b5dd8 ) 329 | ----- Split Coin Results ---- 330 | Updated Coin : Coin { id: 0x9f9a9bce97390e0cc2580b337f6f25c77b031668, value: 99949907 } 331 | New Coins : Coin { id: 0xcce677fe40fb33fb5825498b2d379985c4f080c4, value: 99949907 } 332 | Updated Gas : Coin { id: 0x25500da23617b95f5cc40c6695f12ac97c29b9fa, value: 99948788 } 333 | 334 | 6. 合约调用 335 | sui合约初始化函数init 336 | https://github.com/MystenLabs/sui/blob/main/crates/sui-verifier/src/lib.rs#L20 337 | 338 | 每个sui module可以设置一个init函数(在publish的时候完成初始化), 最多只有两个参数, 339 | (TxContext) 或 (Struct, TxContext) 340 | 341 | (1) 启动临时测试网: 342 | $ sui-test-validator 343 | Fullnode RPC URL: http://127.0.0.1:9000 344 | Fullnode Websocket URL: 127.0.0.1:9001 345 | Gateway RPC URL: http://127.0.0.1:5001 346 | Faucet URL: http://127.0.0.1:9123 347 | 348 | (2) 切换目录 349 | cd sui/sui_programmability/examples/fungible_tokens 350 | 351 | (3) 准备2个测试账户 352 | 新建2个目录: account1和account2, 使用sui keytool generate ed25519创建新账户 353 | 最终结果如下: 354 | $ cat account1/0x43e298abf29753ca0638637c98a1b5dfc766bccf.key 355 | [ 356 | "AMbJQfNGb5jYS66TzSCYpOt2SKe/NWy/++6hYKozZoMRpeShBjqifL4lMmw163mrEvLFecoI/QEi9p7tbPTMfFE=" 357 | ] 358 | 359 | $ cat account1/client.yaml 360 | --- 361 | keystore: 362 | File: /home/chain/workrust/sui/sui_programmability/examples/fungible_tokens/account1/0x43e298abf29753ca0638637c98a1b5dfc766bccf.key 363 | gateway: 364 | rpc: 365 | - "http://127.0.0.1:5001" 366 | active_address: "0x43e298abf29753ca0638637c98a1b5dfc766bccf" 367 | fullnode: ~ 368 | 369 | $ cat account2/0x967669e360b1d8d860459ca3978d76a895ee292f.key 370 | [ 371 | "ABcvObCLf9kDCjKTHjxZy28h/yScv61X0qChL+IovRGz52ZHZGwcj1q2IlklJ5ifR+cjl5Ku0bgKodoSGMcu5Kc=" 372 | ] 373 | 374 | $ cat account2/client.yaml 375 | --- 376 | keystore: 377 | File: /home/chain/workrust/sui/sui_programmability/examples/fungible_tokens/account2/0x967669e360b1d8d860459ca3978d76a895ee292f.key 378 | gateway: 379 | rpc: 380 | - "http://127.0.0.1:5001" 381 | active_address: "0x967669e360b1d8d860459ca3978d76a895ee292f" 382 | fullnode: ~ 383 | 384 | 测试一下: 385 | $ sui client --client.config="account1/client.yaml" active-address 386 | 0x43e298abf29753ca0638637c98a1b5dfc766bccf 387 | $ sui client --client.config="account2/client.yaml" active-address 388 | 0x967669e360b1d8d860459ca3978d76a895ee292f 389 | 390 | 领sui测试币 391 | $ curl -H "Content-Type: application/json" \ 392 | -X POST \ 393 | -d '{"recipient":"0x43e298abf29753ca0638637c98a1b5dfc766bccf"}' \ 394 | "http://127.0.0.1:9123/faucet" 395 | {"ok":true} 396 | 397 | $ curl -H "Content-Type: application/json" \ 398 | -X POST \ 399 | -d '{"recipient":"0x967669e360b1d8d860459ca3978d76a895ee292f"}' \ 400 | "http://127.0.0.1:9123/faucet" 401 | {"ok":true} 402 | 403 | (4) 检查代理, 浏览器打开 https://explorer.devnet.sui.io/, 选择Local 404 | 405 | (5) 部署 FungibleTokens 合约 406 | $ sui client --client.config="account1/client.yaml" publish --gas-budget 10000 407 | 408 | 部分关键信息如下: 409 | package : 0x3fd65126702428870d4f8263c876ee35b6149399 410 | abc::Registry: 0x522b9cb893a607409f77d42b484773dd8523f655 411 | RegulatedCoin: 0x6473ce590af3b0274e0ab0d1a3ce2886f407bcc4 412 | abc::AbcTreasuryCap: 0x92befce929b4194dbf5c989ee4e2ca506dd9c52f 413 | 414 | (6) account1 调用 abc::mint 415 | $ sui client --client.config="account1/client.yaml" call \ 416 | --gas-budget 10000 \ 417 | --package 0x3fd65126702428870d4f8263c876ee35b6149399 \ 418 | --module "abc" \ 419 | --function "mint" \ 420 | --args "0x92befce929b4194dbf5c989ee4e2ca506dd9c52f" \ 421 | "0x6473ce590af3b0274e0ab0d1a3ce2886f407bcc4" \ 422 | 10000 423 | 424 | (7) account1 调用 abc::create 425 | $ sui client --client.config="account1/client.yaml" call \ 426 | --gas-budget 10000 \ 427 | --package 0x3fd65126702428870d4f8263c876ee35b6149399 \ 428 | --module "abc" \ 429 | --function "create" \ 430 | --args "0x92befce929b4194dbf5c989ee4e2ca506dd9c52f" \ 431 | "0x967669e360b1d8d860459ca3978d76a895ee292f" 432 | 433 | $ sui client --client.config="account1/client.yaml" objects 434 | 435 | 得新的object 0x11809317d32a9237dc40ef51c3eb76f3904436f0 436 | 437 | (8) account1 调用 abc::transfer 438 | $ sui client --client.config="account1/client.yaml" call \ 439 | --gas-budget 10000 \ 440 | --package 0x3fd65126702428870d4f8263c876ee35b6149399 \ 441 | --module "abc" \ 442 | --function "transfer" \ 443 | --args "0x522b9cb893a607409f77d42b484773dd8523f655" \ 444 | "0x6473ce590af3b0274e0ab0d1a3ce2886f407bcc4" 445 | 1000 \ 446 | "0x967669e360b1d8d860459ca3978d76a895ee292f" 447 | 448 | 得新的object 0x7ee38468711ada525091db16a36d98b745a24685 449 | 450 | (9) account2 调用 abc::accept_transfer 451 | $ sui client --client.config="account2/client.yaml" call \ 452 | --gas-budget 10000 \ 453 | --package 0x3fd65126702428870d4f8263c876ee35b6149399 \ 454 | --module "abc" \ 455 | --function "accept_transfer" \ 456 | --args "0x522b9cb893a607409f77d42b484773dd8523f655" \ 457 | "0x11809317d32a9237dc40ef51c3eb76f3904436f0" \ 458 | "0x7ee38468711ada525091db16a36d98b745a24685" 459 | 460 | 3. [Aptos和Sui Move合约开发有哪些异同](./aptos_vs_sui.md) 461 | 462 | 4. ****Awesome Move**** 463 | 464 | https://github.com/MystenLabs/awesome-move 465 | 466 | 5. ****Move Tutorial:**** 467 | 468 | https://github.com/move-language/move/tree/main/language/documentation/tutorial 469 | 470 | 6. ****明星公链Aptos初体验--发送交易和构建合约**** 471 | 472 | https://learnblockchain.cn/article/4466 473 | 474 | ****无需合约,在Aptos上发行一个nft**** 475 | 476 | https://learnblockchain.cn/article/4473 477 | 478 | ****全方位讲解Move开发测试部署工具栈**** 479 | 480 | https://learnblockchain.cn/article/3005 481 | 482 | 483 | 6. **[Global Storage - Operators](https://move-language.github.io/move/global-storage-operators.html#global-storage---operators)** 484 | 485 | - 用key修饰的struct, 可以通过 move_to 放到链上,有相应的地址 486 | - 用store修饰的struct, 一般作为被key 修饰的struct的字段, 存在链上 487 | - 用copy修饰的struct,可以隐式的复制struct的值, 488 | - 用drop修饰的struct, 一般作为被key 修饰的struct的字段, 从链上删除 489 | 490 | key,store,drop控制的是我的资源要不要放到链上,要不要从链上删除,copy 更多的是用到中间处理过程中 491 | 492 | 7. ****aptos公钥转地址**** 493 | 494 | ed25519公钥是32字节, AuthenticationKey也是32字节, AccountAddress有16,20,32字节,aptos keygen工具用的是32字节的AccountAddress 495 | 496 | 32字节的AccountAddress等于32字节的AuthenticationKey 497 | 498 | 以ed25519公钥为例计算对应的地址(AccountAddress) 499 | 500 | (1) 取32字节ed25519公钥+1字节Scheme 501 | 502 | **32字节公钥**: C0DE9BE730372641908F9DADD560E4B10C644051ED947E8E148A7833A71DA00A00 503 | 504 | **1字节Scheme**: 505 | 506 | 00 (ed25519对应00) 507 | 508 | https://github.com/aptos-labs/aptos-core/blob/main/types/src/transaction/authenticator.rs#L241 509 | 510 | (2) 对33字节数据进行Sha3-256 hash即得32字节的AuthenticationKey,也就是32字节的地址 511 | 512 | **33字节preimage**: 513 | C0DE9BE730372641908F9DADD560E4B10C644051ED947E8E148A7833A71DA00A0000 514 | 515 | **AuthenticationKey:** 516 | 517 | 845f4d5332df61d39d77c19f1af2bae1af5a803ee11f323eeed72b054ff10002 518 | 519 | **AccountAddress:** 520 | 521 | 845f4d5332df61d39d77c19f1af2bae1af5a803ee11f323eeed72b054ff10002 522 | 523 | 在线工具: https://emn178.github.io/online-tools/sha3_256.html 524 | 525 | (Input type选Hex, Hash算法选SHA3-256) 526 | 527 | 8. [如何在Aptos上发行coin?](./mycoin/README.md) 528 | 9. [如何在Aptos上用多签账户转账(coin)?](./multisig-transaction/README.md) 529 | 10. [为什么要创造 Sui 版本的Move](https://move-china.com/topic/144) 530 | 531 | 11. [直接transfer aptosnames域名NFT](./aptosname-transfer) 532 | 533 | publish tx result on aptos mainnet 534 | ```txt 535 | { 536 | "Result": { 537 | "transaction_hash": "0x6995a293f280211742beb8b1b0d2cf03e408ed369991467d550452560523c82c", 538 | "gas_used": 6830, 539 | "gas_unit_price": 100, 540 | "sender": "a24881e004fdbc5550932bb2879129351c21432f21f32d94bf11603bebd9f5c0", 541 | "sequence_number": 10, 542 | "success": true, 543 | "timestamp_us": 1666612074120064, 544 | "version": 10634090, 545 | "vm_status": "Executed successfully" 546 | } 547 | } 548 | ``` 549 | 12. Aptos 传递数组 550 | ```move 551 | module 0x0::vector { 552 | use std::string::String; 553 | use std::vector; 554 | 555 | public entry fun vec( 556 | _from: &signer, 557 | _collection_name: String, 558 | token_names: vector, 559 | token_uris: vector, 560 | addresses: vector
, 561 | _token_des: String 562 | ) { 563 | assert!(vector::length(&token_names) > 0, 1); 564 | assert!(vector::length(&token_uris) > 0, 2); 565 | assert!(vector::length(&addresses) > 0, 3); 566 | } 567 | } 568 | ``` 569 | ```js 570 | let collection_name = BCS.bcsSerializeStr("test collection"); 571 | let token_names = BCS.serializeVectorWithFunc(["token1", "token2"], "serializeStr"); 572 | let token_uris = BCS.serializeVectorWithFunc(["uri1", "uri2"], "serializeStr"); 573 | let token_des = BCS.bcsSerializeStr("test des"); 574 | let addresses = BCS.serializeVectorWithFunc( 575 | [ 576 | new HexString("0xdcf3f5381c94de140d2bdf597e200cbfb3ac4ebcb7abd718e406a2d473c5de88").toUint8Array(), 577 | new HexString("0x97543d1f442fb3725935b53b3612f989dd0fdaa4b855baca0c36df9a9aa23a74").toUint8Array() 578 | ], 579 | "serializeFixedBytes" 580 | ); 581 | ``` 582 | 583 | 13. Sui 传递数组 584 | ```move 585 | module 0x0::vector { 586 | use std::vector; 587 | use sui::coin::Coin; 588 | use sui::sui::SUI; 589 | use sui::pay; 590 | 591 | public entry fun vec( 592 | self: &mut Coin, 593 | vec_bool: vector, 594 | vec_u8: vector, 595 | vec_u64: vector, 596 | vec_address: vector
, 597 | vec_coins: vector> 598 | ) { 599 | assert!(vector::length(&vec_bool) > 0, 1); 600 | assert!(vector::length(&vec_u8) > 0, 2); 601 | assert!(vector::length(&vec_u64) > 0, 3); 602 | assert!(vector::length(&vec_address) > 0, 4); 603 | 604 | pay::join_vec(self, vec_coins) 605 | } 606 | } 607 | ``` 608 | [sui传递vector有三种方式]((./sui-vector/README.md)) 609 | 610 | `ascii字符串`, `hex字符串`, `vec sui-json` 611 | 612 | 下面是hex字符串格式 613 | ```js 614 | const txn = await signer.executeMoveCallWithRequestType({ 615 | packageObjectId: '0xce6cab8be08edcfb12e2f26c2ac288de35a0b9a6', 616 | module: 'vector', 617 | function: 'vec', 618 | typeArguments: [], 619 | arguments: [ 620 | '0xdbdae62c692525b893b33e413664946ef07ef30c', 621 | '[true]', 622 | '0x1234', 623 | '[78, 89, 32]', 624 | '["0xb811881d75c77acec51ff1622a3cc1bd6b247707"]', 625 | '["0xccfe11e303b81749a2c3a1288e73e4cf88843844"]' 626 | ], 627 | gasBudget: DEFAULT_GAS_BUDGET, 628 | gasPayment: coins[0].objectId, 629 | }); 630 | ``` 631 | 632 | 14. [Aptos getTableItem](./aptosname-transfer/src/get_token.js) 633 | 634 | 15. [Sui 获取table或bag的所有key](./sui-scripts/src/get_objects.js) 635 | 636 | 16. dynamic_field和dynamic_object_field的区别 637 | ```txt 638 | 1. table和bag的区别 639 | table的key和value类型初始化的时候就已经确定了,table只能存储同类型的key和value, 640 | bag初始化的时候未限制具体类型,bag能存储不同类型的key和value。 641 | 642 | 2. dynamic_field和dynamic_object_field的区别 643 | 类似的table和object_table,bag和object_bag的区别,本质上也是dynamic_field和dynamic_object_field的区别 644 | (1) key的处理: 为了防止和dynamic_field key值冲突, dynamic_object_field对key类型进行了Wrapper。 645 | (2) 加入存储的是一个object: 646 | 用dynamic_field存储,通过dynamic_field key值可以直接取到这个object的值,此时用object id在链上进行查询是查不到的 647 | 用dynamic_object_field存储, 通过dynamic_object_field key值取到的是这个object id, 需要用object id在链上再次查询才能获取到这个object的值 648 | ``` 649 | 650 | 17. [链下计算table和object_table的key](./hash_type_and_key/README.md) 651 | 652 | 18. [通过sui_devInspectMoveCall可以链下调用move合约中的public函数](./sui-scripts/src/devInspectMoveCall.js) -------------------------------------------------------------------------------- /aptos_vs_sui.md: -------------------------------------------------------------------------------- 1 | # Aptos和Sui Move合约开发有哪些异同 2 | 3 | ## 简介 4 | 先介绍了从`code和data一起` 到 `code和data分离` 这种智能合约开发范式转移, 5 | 再通过[在Aptos和Sui上BTC跨链镜像资产合约实例](https://github.com/OmniBTC/OmniBridge), 介绍了Aptos和Sui合约开发的异同点 6 | 7 | ## 智能合约开发范式转移 8 | 9 | #### 哈佛结构和冯·诺依曼结构 10 | 学过计算机体系结构的都知道, 哈佛结构和冯·诺依曼结构。 11 | 12 | 哈佛结构出现的更早, 当时的计算机设计, 程序和数据是俩个截然不同的概念, 13 | 数据放在存储器中,而程序作为控制器的一部分. 14 | 这种架构灵活性较差, 需要技术员既要懂硬件设计,又要懂程序设计. 15 | 16 | 冯·诺依曼结构中, 将程序和数据一样看待, 将程序编码为数据,然后与数据一同存放在存储器中, 17 | 这样计算机就可以调用存储器中的程序来处理数据. 程序不再是控制器的一部分了. 18 | 这种设计思想导致了硬件和软件的分离, 即硬件设计和程序设计可以分开执行!!! 19 | 这就催生了程序员这个职业的诞生!!! 20 | 21 | 哈佛结构在嵌入式芯片行业常见(比如ARM9~ARM11芯片, 而ARM7系列则采用了冯·诺依曼结构) 22 | 而PC和服务器芯片基本是冯·诺依曼结构. 23 | 24 | 可以说, 互联网程序员都是在冯·诺依曼结构下进行程序设计. 25 | 26 | 简单地, 哈佛结构就是`code和data分离`, 冯·诺依曼结构就是`code和data一起`. 27 | 28 | #### 区块链虚拟机与智能合约开发 29 | 30 | 虚拟机执行智能合约始终围绕着这个核心问题: 31 | (1) Where: 合约要处理的数据在哪 32 | - `code和data一起`: data处于code所在的作用域, code随时读取data. 33 | - `code和data分离`: 将data或data的位置传给code, 且code只能处理这些给定的数据(无法访问其他数据). 34 | 35 | 而合约开发者更关心: 36 | (2) Who: 谁能访问这些数据 37 | (3) How:如何处理这些数据(业务逻辑) 38 | 39 | 简单地, 我们把常见的区块链虚拟机分类: 40 | 41 | - `EVM`: `code和data一起` 42 | - `WASM`: `code和data一起` 43 | - `Solana-BPF`: `code和data分离` 44 | - `Aptos-Move`: `code和data分离` 45 | - `Sui-Move`: `code和data分离` 46 | 47 | 因为不需要关心data的存储位置(就像冯·诺依曼结构下, 程序员不需要懂硬件电路一样), 48 | 49 | 所以对于互联网程序员来说, 在`EVM`和`WASM`上编写合约程序更简单. 50 | 51 | 如果在`Solana-BPF`,`Aptos-Move`,`Sui-Move`上开发智能合约, 52 | 就需要像硬件工程师关心数据控制器一样去关心data的位置: 53 | 54 | - `Solana合约`: 调用者需要指定访问data的地址及其读写属性. 55 | - `Sui合约`: 与solana类似, 调用者需要指定访问data的object-id. 56 | - `Aptos合约`: 更简单, 数据通过move_to和signer绑定, 又通过将合约部署者和合约绑定, 57 | 使得合约也可以拥有自己的状态数据, 调用者不再需要自己指定访问data(但需要调用者提前注册data, 完成move_to绑定) 58 | 59 | 合约开发难度 `solana` > `sui` > `aptos` 60 | 61 | ## Aptos和Sui智能合约开发对比 62 | 在Aptos和Sui上, 分别实现了BTC跨链镜像资产合约 63 | 64 | [OmniBridge 源码链接](https://github.com/OmniBTC/OmniBridge) 65 | 66 | - 相同点: [Aptos和Sui使用的是相同的VM和智能合约开发语言](https://github.com/move-language/move) 67 | - 不同点: 68 | - **(1) Aptos和Sui的VM库函数(供合约内部调用)不同.** 69 | ```bash 70 | 为了防止重复deposit, 需要一个队列存储已deposit的请求 71 | 72 | bridge-aptos 的 iterable_table底层用的是table(定义在AptosStdlib) 73 | bridge-sui 的 vec_queue底层用的是vector(定义在MoveStdlib) 74 | ``` 75 | - **(2) Aptos用户合约package地址是合约部署者的地址, 而Sui则将所有用户合约地址统一到`0x0`地址下.** 76 | ```bash 77 | bridge::initialize只能由合约的owner调用 78 | 79 | bridge-aptos 中可以直接用 "@owner"进行对比 80 | bridge-sui 中只能在init时将creator先保存到Info中, 调用initialize时在取出对比 81 | ``` 82 | - **(3) Aptos用户需要自己定义调用initialize等函数完成合约的初始化, 而Sui用户只需要自己定义init函数(不能传自定义参数), 合约部署的时候完成初始化.** 83 | ```bash 84 | admin和controller只能被初始化一次 85 | 86 | bridge-aptos 中的initialize做了存在性检查, 确保admin和controller只被初始化一次 87 | bridge-sui 中的init先初始化一个object, 在调用initialize完成最后的初始化 88 | ``` 89 | - (4) **Aptos resource不能直接转移到receiver地址, 而Sui object可以直接转移到receiver地址.** 90 | ```bash 91 | XBTC的transfer 92 | 93 | bridge-aptos 需要先xbtc::register, 再xbtc::transfer 94 | bridge-sui 只需一步xbtc::split_and_transfer 95 | ``` 96 | - (5) **Aptos中的fungible tokens不需要`merge`操作, 而Sui则提供了`merge`,以便将很多小额objects合并为1个object.** 97 | ```bash 98 | XBTC的transfer 99 | 100 | bridge-sui xbtc::join和xbtc::join_vec 101 | ``` 102 | - (6) **Aptos合约内通过move_to将resource和signer绑定, 而Sui合约内禁用move_to.** 103 | ```bash 104 | bridge-sui xbtc::init 调用move_to, 编译时报如下错误 105 | 106 | ExecutionErrorInner { 107 | kind: SuiMoveVerificationError, 108 | source: Some( 109 | "Access to Move global storage is not allowed. 110 | Found in function init: [MoveTo(StructDefinitionIndex(1))]" 111 | ) 112 | } 113 | ``` 114 | - (7) **Aptos中可以使用`public(script)`, 而Sui则废弃了`public(script)`.** 115 | ```bash 116 | bridge-sui 中使用`public(script)`, 编译时报如下错误 117 | 118 | 'public(script)' is deprecated in favor of the 'entry' modifier. Replace with 'public entry' 119 | ``` 120 | - (8) **Aptos地址是32字节, 而Sui地址是20字节.** 121 | ```bash 122 | bridge-aptos admin example: 0xa24881e004fdbc5550932bb2879129351c21432f21f32d94bf11603bebd9f5c0 123 | bridge-sui admin example: 0xdea83a5c27ef936cd9efd3bc596696e1d101d647 124 | ``` 125 | - (9) **Aptos合约支持升级, 而Sui合约目前不支持升级.** 126 | ```bash 127 | bridge-aptos upgrade-policy 128 | 129 | `arbitrary`, `compatible`, `immutable` 对应 0, 1,2 130 | 0 不做任何检查,强制替换code, 131 | 1 做兼容性检查(同样的public 函数,不能改变已有Resource的内存布局) 132 | 2 禁止升级 133 | 每次publish的时候会比较链上的policy和此次publish的policy(默认是1), 134 | 只有此次的policy小于链上的policy时才允许合约升级 135 | ``` 136 | - (10) **在move合约调用请求与合约接口之间这一层的处理不同.** 137 | 138 | - 比如 Aptos的合约参数只能是基本类型, 而Sui则可以是自定义结构(调用传参时传object-id)且最后一个参数只能是TxContext. 139 | 140 | - 比如 Aptos的signer绑定了resource, 因此合约可以通过signer访问相应的data, 而Sui只能通过调用者传递的object-id访问相应的data. 141 | 142 | - 比如 Aptos合约在做自定义访问控制时更容易, 而Sui合约的访问控制可能会在不同的object中, 这就要求开发者主动关联这些objects, 很容易产生合约安全漏洞. 143 | ```bash 144 | bridge-sui bridge::deposit 函数签名及函数调用 145 | 146 | public entry fun deposit( 147 | account: &signer, 148 | receiver: address, 149 | amount: u64, 150 | memo: String, 151 | ) acquires Info 152 | 153 | aptos move run \ 154 | --private-key=$PRIVATE \ 155 | --url=http://127.0.0.1:8080 \ 156 | --function-id=0xa24881e004fdbc5550932bb2879129351c21432f21f32d94bf11603bebd9f5c0::bridge::deposit \ 157 | --args address:0xa24881e004fdbc5550932bb2879129351c21432f21f32d94bf11603bebd9f5c0 u64:10000000 string:"test" \ 158 | 159 | 160 | bridge-sui bridge::deposit 函数签名及函数调用 161 | 162 | public entry fun deposit( 163 | info: &mut Info, 164 | xbtc_cap: &mut TreasuryCap, 165 | receiver: address, 166 | amount: u64, 167 | memo: vector, 168 | ctx: &mut TxContext 169 | ) 170 | 171 | sui client call --gas-budget 10000 \ 172 | --package 0xc087a76e0495c395db814587688930b7fd808cad \ 173 | --module "bridge" \ 174 | --function "deposit" \ 175 | --args 0xe57396fb7f2c09ffb0fec0af7e175d106dc18253 \ 176 | 0x5c3d9503d9963c0887b13e6b1cca4c9ca341d39d \ 177 | 0xdea83a5c27ef936cd9efd3bc596696e1d101d647 \ 178 | 100000 \ 179 | "test" 180 | ``` 181 | 182 | 183 | 184 | -------------------------------------------------------------------------------- /aptos_vs_sui_en.md: -------------------------------------------------------------------------------- 1 | ## The differences of smart contract programming on Aptos and Sui 2 | through the comparison and analysis of OmniBTC's mirror BTC Move code. 3 | 4 | 5 | ## Intro 6 | First introduces the paradigm shift of smart contract development, 7 | from `code and data together` to `code and data separation`. 8 | 9 | Then through the example of [BTC cross-chain mirror asset move contracts](https://github.com/OmniBTC/OmniBridge), 10 | the differences between Aptos and Sui contract programing are introduced. 11 | 12 | ## Paradigm Shift in Smart Contract Programming 13 | 14 | #### Harvard vs Von Neumann Architecture 15 | Anyone who has studied computer architecture knows that Harvard and Von Neumann Architecture. 16 | 17 | The `Harvard Architecture` appeared earlier. In computer design at the time, program and data were two completely different concepts. 18 | The data is placed in memory and the program is part of the controller. 19 | This architecture is less flexible and requires technicians to understand both hardware design and programming. 20 | 21 | In the `Von Neumann Architecture`, the program is treated like data. The program is encoded as data, 22 | and then stored in memory together with the data. This way the computer can call programs in memory to process the data. 23 | The program is no longer part of the controller. This design thinking leads to the separation of hardware and software, 24 | that is, hardware design and programming can be performed separately! ! ! This gave birth to the career of programmers! ! ! 25 | 26 | The `Harvard Architecture` is common in the embedded chip industry (such as ARM9~ARM11 chips, while the ARM7 series adopts the Von Neumann Architecture) 27 | PC and server chips are basically `Von Neumann Architecture`. 28 | 29 | It can be said that Internet programmers are all programming under the `Von Neumann Architecture`. 30 | 31 | In short, the `Harvard Architecture` is `code and data separated`, and the `Von Neumann Architecture` is `code and data together`. 32 | 33 | #### BlockChain VM and Smart Contract 34 | VM executing smart contracts always revolve around this core question: 35 | (1) `Where`: Where is the data to be processed by the contract 36 | - `code and data together`: The data is within the scope of the code, and the code can read the data at any time. 37 | - `code and data separation`: Pass data or data location to code, code can only process these given data (can not access other data). 38 | 39 | The smart contract programmer are more concerned with: 40 | (2) `Who`: Who can access the data 41 | (3) `How`: How to process this data (business logic) 42 | 43 | In short, we classify common blockchain virtual machines: 44 | - `EVM`: `code and data together` 45 | - `WASM`: `code and data together` 46 | - `Solana-BPF`: `code and data separation` 47 | - `Aptos-Move`: `code and data separation` 48 | - `Sui-Move`: `code and data separation` 49 | 50 | Because there is no need to care where the data is stored (as in the Von Neumann Architecture, the programmer does not need to know the hardware circuit), 51 | 52 | So it is easier for Web2 programmers to write contract programs on `EVM` and `WASM`. 53 | 54 | If you write smart contracts on `Solana-BPF`, `Aptos-Move`, `Sui-Move`, 55 | You need to care about the location of the data, just like the hardware engineer cares about the data controller: 56 | - `Solana contract`: 57 | The caller needs to specify the address to access the data and its read/write properties. 58 | - `Sui contract`: 59 | Similar to solana, the caller needs to specify the object-id to access the data. 60 | - `Aptos contract`: 61 | Simpler, data is bound to signer through `move_to`, contract deployer is bound to contract, 62 | the contract can also have its own state data. And the caller no longer needs to specify the access 63 | data (but the caller needs to register the data in advance and complete the move_to binding). 64 | 65 | ## Example Comparison 66 | Implemented BTC cross-chain mirror asset contracts on Aptos and Sui respectively 67 | 68 | [OmniBridge Source Code](https://github.com/OmniBTC/OmniBridge) 69 | 70 | - `Similarities`: [Aptos and Sui use the same VM and smart contract development language](https://github.com/move-language/move) 71 | - `Differences`: 72 | - **(1) Aptos and Sui's VM library functions (for internal calls of contracts) are different.** 73 | ```bash 74 | To prevent duplicate deposits, a queue is required to store deposited requests 75 | 76 | Table(defined in AptosStdlib) used internally by bridge-aptos's iterable_table. 77 | vector(defined in MoveStdlib) used internally by bridge-sui's vec_queue. 78 | ``` 79 | 80 | - **(2) Aptos user contract package address is the address of the contract deployer, while Sui unifies all user contract addresses under the `0x0` address.** 81 | ```bash 82 | bridge::initialize can only be called by the contract owner 83 | 84 | In bridge-aptos, you can use "@owner" directly for comparison 85 | In bridge-sui, the creator can only save to Info at init, and take out the comparison when calling initialize. 86 | ``` 87 | - **(3) Aptos user need to define and call initialize and other functions to complete the initialization of the contract, while Sui user only need to define the init function (can not pass custom parameters), and complete the initialization when the contract is deployed.** 88 | ```bash 89 | admin and controller can only be initialized once 90 | 91 | The initialization in bridge-aptos checks for existence to ensure that the admin and controller are only initialized once. 92 | The init in bridge-sui first initializes an object, and then calls initialize to complete the final initialization. 93 | ``` 94 | - (4) **Aptos resource cannot be directly transferred to receiver address, while Sui object can be directly transferred to receiver address.** 95 | ```bash 96 | transfer XBTC 97 | 98 | bridge-aptos needs xbtc::register first, then xbtc::transfer 99 | bridge-sui just one step, xbtc::split_and_transfer 100 | ``` 101 | - (5) **Fungible tokens in Aptos do not require `merge` operation, while Sui provides `merge` to merge many small objects into 1 object.** 102 | ```bash 103 | transfer XBTC 104 | 105 | bridge-sui xbtc::join and xbtc::join_vec 106 | ``` 107 | - (6) **Resources and signers are bound by move_to in Aptos contracts and disabled in Sui contracts.** 108 | ```bash 109 | bridge-sui if call move_to in xbtc::init, and the following error occurs when compiling: 110 | 111 | ExecutionErrorInner { 112 | kind: SuiMoveVerificationError, 113 | source: Some( 114 | "Access to Move global storage is not allowed. 115 | Found in function init: [MoveTo(StructDefinitionIndex(1))]" 116 | ) 117 | } 118 | ``` 119 | - (7) **Aptos can use `public(script)`, while Sui deprecates `public(script)`.** 120 | ```bash 121 | bridge-sui if use `public(script)`, and the following error occurs when compiling: 122 | 123 | 'public(script)' is deprecated in favor of the 'entry' modifier. Replace with 'public entry' 124 | ``` 125 | - (8) **Aptos address is 32 bytes, while Sui address is 20 bytes.** 126 | ```bash 127 | bridge-aptos admin example: 0xa24881e004fdbc5550932bb2879129351c21432f21f32d94bf11603bebd9f5c0 128 | bridge-sui admin example: 0xdea83a5c27ef936cd9efd3bc596696e1d101d647 129 | ``` 130 | - (9) **Aptos contracts support upgrades, while Sui contracts currently do not support upgrades.** 131 | ```bash 132 | bridge-aptos upgrade-policy 133 | 134 | `arbitrary`, `compatible`, `immutable` correspond to 0, 1, 2 135 | 0 does not check, forces code substitution, 136 | 1 Do a compatibility check (the same public function cannot change the memory layout of the existing Resource) 137 | 2 Disable upgrade 138 | Every release will compare the on-chain strategy with the strategy of this release (default is 1), 139 | Contract upgrades are only allowed if the current policy is smaller than the on-chain policy 140 | ``` 141 | - (10) **The layer is handled differently between the move contract call request and the contract interface.** 142 | 143 | - For example, the contract parameters of Aptos can only be primitive types, while Sui can be a custom structure (object-id is passed when calling parameters), and the last parameter can only be TxContext. 144 | - For example, the signer of Aptos is bound to the resource, so the contract can access the corresponding data through the signer, while Sui can only access the corresponding data through the object-id passed by the caller. 145 | - For example, Aptos contract is easier to do custom access control, while the access control of Sui contract may be in different objects, which requires developers to actively associate these objects, and it is easy to generate contract security vulnerabilities. 146 | 147 | ```bash 148 | bridge-sui bridge::deposit 149 | 150 | Function Signature: 151 | public entry fun deposit( 152 | account: &signer, 153 | receiver: address, 154 | amount: u64, 155 | memo: String, 156 | ) acquires Info 157 | 158 | Call: 159 | aptos move run \ 160 | --private-key=$PRIVATE \ 161 | --url=http://127.0.0.1:8080 \ 162 | --function-id=0xa24881e004fdbc5550932bb2879129351c21432f21f32d94bf11603bebd9f5c0::bridge::deposit \ 163 | --args address:0xa24881e004fdbc5550932bb2879129351c21432f21f32d94bf11603bebd9f5c0 \ 164 | u64:100000 \ 165 | string:"test" \ 166 | 167 | 168 | bridge-sui bridge::deposit 169 | 170 | Function Signature: 171 | public entry fun deposit( 172 | info: &mut Info, 173 | xbtc_cap: &mut TreasuryCap, 174 | receiver: address, 175 | amount: u64, 176 | memo: vector, 177 | ctx: &mut TxContext 178 | ) 179 | 180 | Call: 181 | sui client call --gas-budget 10000 \ 182 | --package 0xc087a76e0495c395db814587688930b7fd808cad \ 183 | --module "bridge" \ 184 | --function "deposit" \ 185 | --args 0xe57396fb7f2c09ffb0fec0af7e175d106dc18253 \ 186 | 0x5c3d9503d9963c0887b13e6b1cca4c9ca341d39d \ 187 | 0xdea83a5c27ef936cd9efd3bc596696e1d101d647 \ 188 | 100000 \ 189 | "test" 190 | ``` 191 | -------------------------------------------------------------------------------- /aptosname-transfer/Move.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = 'aptosname-transfer' 3 | version = '1.0.0' 4 | 5 | [dependencies.AptosFramework] 6 | local = "../../aptos-core/aptos-move/framework/aptos-framework/" 7 | [dependencies.AptosToken] 8 | local = "../../aptos-core/aptos-move/framework/aptos-token/" 9 | 10 | 11 | [addresses] 12 | myself = "0xa24881e004fdbc5550932bb2879129351c21432f21f32d94bf11603bebd9f5c0" 13 | 14 | # aptosnames creator 15 | # see https://explorer.aptoslabs.com/account/0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c 16 | # 0x867ed1f6bf916171b1de3ee92849b8978b7d1b9e0a8cc982a3d19d535dfd9c0c::token_helper::CollectionCapabilityV1 17 | aptosnames_creator = "0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838" 18 | 19 | -------------------------------------------------------------------------------- /aptosname-transfer/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "scripts", 3 | "version": "1.0.0", 4 | "lockfileVersion": 2, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "scripts", 9 | "version": "1.0.0", 10 | "license": "ISC", 11 | "dependencies": { 12 | "aptos": "^1.3.16" 13 | } 14 | }, 15 | "node_modules/@noble/hashes": { 16 | "version": "1.1.3", 17 | "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.1.3.tgz", 18 | "integrity": "sha512-CE0FCR57H2acVI5UOzIGSSIYxZ6v/HOhDR0Ro9VLyhnzLwx0o8W1mmgaqlEUx4049qJDlIBRztv5k+MM8vbO3A==", 19 | "funding": [ 20 | { 21 | "type": "individual", 22 | "url": "https://paulmillr.com/funding/" 23 | } 24 | ] 25 | }, 26 | "node_modules/@scure/base": { 27 | "version": "1.1.1", 28 | "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.1.tgz", 29 | "integrity": "sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA==", 30 | "funding": [ 31 | { 32 | "type": "individual", 33 | "url": "https://paulmillr.com/funding/" 34 | } 35 | ] 36 | }, 37 | "node_modules/@scure/bip39": { 38 | "version": "1.1.0", 39 | "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.1.0.tgz", 40 | "integrity": "sha512-pwrPOS16VeTKg98dYXQyIjJEcWfz7/1YJIwxUEPFfQPtc86Ym/1sVgQ2RLoD43AazMk2l/unK4ITySSpW2+82w==", 41 | "funding": [ 42 | { 43 | "type": "individual", 44 | "url": "https://paulmillr.com/funding/" 45 | } 46 | ], 47 | "dependencies": { 48 | "@noble/hashes": "~1.1.1", 49 | "@scure/base": "~1.1.0" 50 | } 51 | }, 52 | "node_modules/aptos": { 53 | "version": "1.3.16", 54 | "resolved": "https://registry.npmjs.org/aptos/-/aptos-1.3.16.tgz", 55 | "integrity": "sha512-LxI4XctQ5VeL+HokjwuGPwsb1fcydLIn4agFXyhn7hSYosTLNRxQ3UIixyP4Fmv6qPBjQVu8hELVSlThQk/EjA==", 56 | "dependencies": { 57 | "@noble/hashes": "1.1.3", 58 | "@scure/bip39": "1.1.0", 59 | "axios": "0.27.2", 60 | "form-data": "4.0.0", 61 | "tweetnacl": "1.0.3" 62 | }, 63 | "engines": { 64 | "node": ">=11.0.0" 65 | } 66 | }, 67 | "node_modules/asynckit": { 68 | "version": "0.4.0", 69 | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", 70 | "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" 71 | }, 72 | "node_modules/axios": { 73 | "version": "0.27.2", 74 | "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz", 75 | "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==", 76 | "dependencies": { 77 | "follow-redirects": "^1.14.9", 78 | "form-data": "^4.0.0" 79 | } 80 | }, 81 | "node_modules/combined-stream": { 82 | "version": "1.0.8", 83 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", 84 | "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", 85 | "dependencies": { 86 | "delayed-stream": "~1.0.0" 87 | }, 88 | "engines": { 89 | "node": ">= 0.8" 90 | } 91 | }, 92 | "node_modules/delayed-stream": { 93 | "version": "1.0.0", 94 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", 95 | "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", 96 | "engines": { 97 | "node": ">=0.4.0" 98 | } 99 | }, 100 | "node_modules/follow-redirects": { 101 | "version": "1.15.2", 102 | "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", 103 | "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", 104 | "funding": [ 105 | { 106 | "type": "individual", 107 | "url": "https://github.com/sponsors/RubenVerborgh" 108 | } 109 | ], 110 | "engines": { 111 | "node": ">=4.0" 112 | }, 113 | "peerDependenciesMeta": { 114 | "debug": { 115 | "optional": true 116 | } 117 | } 118 | }, 119 | "node_modules/form-data": { 120 | "version": "4.0.0", 121 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", 122 | "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", 123 | "dependencies": { 124 | "asynckit": "^0.4.0", 125 | "combined-stream": "^1.0.8", 126 | "mime-types": "^2.1.12" 127 | }, 128 | "engines": { 129 | "node": ">= 6" 130 | } 131 | }, 132 | "node_modules/mime-db": { 133 | "version": "1.52.0", 134 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", 135 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", 136 | "engines": { 137 | "node": ">= 0.6" 138 | } 139 | }, 140 | "node_modules/mime-types": { 141 | "version": "2.1.35", 142 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", 143 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", 144 | "dependencies": { 145 | "mime-db": "1.52.0" 146 | }, 147 | "engines": { 148 | "node": ">= 0.6" 149 | } 150 | }, 151 | "node_modules/tweetnacl": { 152 | "version": "1.0.3", 153 | "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", 154 | "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" 155 | } 156 | }, 157 | "dependencies": { 158 | "@noble/hashes": { 159 | "version": "1.1.3", 160 | "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.1.3.tgz", 161 | "integrity": "sha512-CE0FCR57H2acVI5UOzIGSSIYxZ6v/HOhDR0Ro9VLyhnzLwx0o8W1mmgaqlEUx4049qJDlIBRztv5k+MM8vbO3A==" 162 | }, 163 | "@scure/base": { 164 | "version": "1.1.1", 165 | "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.1.tgz", 166 | "integrity": "sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA==" 167 | }, 168 | "@scure/bip39": { 169 | "version": "1.1.0", 170 | "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.1.0.tgz", 171 | "integrity": "sha512-pwrPOS16VeTKg98dYXQyIjJEcWfz7/1YJIwxUEPFfQPtc86Ym/1sVgQ2RLoD43AazMk2l/unK4ITySSpW2+82w==", 172 | "requires": { 173 | "@noble/hashes": "~1.1.1", 174 | "@scure/base": "~1.1.0" 175 | } 176 | }, 177 | "aptos": { 178 | "version": "1.3.16", 179 | "resolved": "https://registry.npmjs.org/aptos/-/aptos-1.3.16.tgz", 180 | "integrity": "sha512-LxI4XctQ5VeL+HokjwuGPwsb1fcydLIn4agFXyhn7hSYosTLNRxQ3UIixyP4Fmv6qPBjQVu8hELVSlThQk/EjA==", 181 | "requires": { 182 | "@noble/hashes": "1.1.3", 183 | "@scure/bip39": "1.1.0", 184 | "axios": "0.27.2", 185 | "form-data": "4.0.0", 186 | "tweetnacl": "1.0.3" 187 | } 188 | }, 189 | "asynckit": { 190 | "version": "0.4.0", 191 | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", 192 | "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" 193 | }, 194 | "axios": { 195 | "version": "0.27.2", 196 | "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz", 197 | "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==", 198 | "requires": { 199 | "follow-redirects": "^1.14.9", 200 | "form-data": "^4.0.0" 201 | } 202 | }, 203 | "combined-stream": { 204 | "version": "1.0.8", 205 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", 206 | "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", 207 | "requires": { 208 | "delayed-stream": "~1.0.0" 209 | } 210 | }, 211 | "delayed-stream": { 212 | "version": "1.0.0", 213 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", 214 | "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" 215 | }, 216 | "follow-redirects": { 217 | "version": "1.15.2", 218 | "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", 219 | "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==" 220 | }, 221 | "form-data": { 222 | "version": "4.0.0", 223 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", 224 | "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", 225 | "requires": { 226 | "asynckit": "^0.4.0", 227 | "combined-stream": "^1.0.8", 228 | "mime-types": "^2.1.12" 229 | } 230 | }, 231 | "mime-db": { 232 | "version": "1.52.0", 233 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", 234 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" 235 | }, 236 | "mime-types": { 237 | "version": "2.1.35", 238 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", 239 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", 240 | "requires": { 241 | "mime-db": "1.52.0" 242 | } 243 | }, 244 | "tweetnacl": { 245 | "version": "1.0.3", 246 | "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", 247 | "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" 248 | } 249 | } 250 | } 251 | -------------------------------------------------------------------------------- /aptosname-transfer/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "scripts", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "aptos": "^1.3.16" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /aptosname-transfer/sources/transfer.move: -------------------------------------------------------------------------------- 1 | module myself::functions { 2 | use std::signer; 3 | use std::string::{String, utf8}; 4 | use aptos_token::token; 5 | 6 | const ERR_REQUIRE_ALLOW_RECEIVE: u64 = 555; 7 | const ERR_INSUFFICIENT_BALANCE: u64 = 556; 8 | 9 | public entry fun allow_receive( 10 | account: &signer 11 | ) { 12 | token::initialize_token_store(account); 13 | token::opt_in_direct_transfer(account, true); 14 | } 15 | 16 | public entry fun aptosname_transfer( 17 | from: &signer, 18 | aptosname: String, 19 | to: address, 20 | ) { 21 | let token_data_id = token::create_token_data_id( 22 | @aptosnames_creator, 23 | utf8(b"Aptos Names V1"), 24 | aptosname 25 | ); 26 | let token_property_version = token::get_tokendata_largest_property_version( 27 | @aptosnames_creator, 28 | token_data_id 29 | ); 30 | 31 | let token_id = token::create_token_id( 32 | token_data_id, 33 | token_property_version 34 | ); 35 | 36 | assert!( 37 | token::has_token_store(to), 38 | ERR_REQUIRE_ALLOW_RECEIVE, 39 | ); 40 | assert!( 41 | token::balance_of(signer::address_of(from), token_id) > 0, 42 | ERR_INSUFFICIENT_BALANCE, 43 | ); 44 | 45 | token::transfer(from, token_id, to, 1); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /aptosname-transfer/src/get_token.js: -------------------------------------------------------------------------------- 1 | const {AptosClient} = require("aptos"); 2 | 3 | const NODE_URL = "https://fullnode.mainnet.aptoslabs.com/v1"; 4 | 5 | (async () => { 6 | const client = new AptosClient(NODE_URL); 7 | 8 | const collectionName = "Aptos Names V1"; 9 | const tokenName = "aptos.apt"; 10 | const creator = "0x305a97874974fdb9a7ba59dc7cab7714c8e8e00004ac887b6e348496e1981838"; 11 | const account = "0xb27f7d329f6d2c8867e5472958c3cfabc781300ca9649f244e267e1d6b966c94"; 12 | const tokenStore = "0x3::token::TokenStore"; 13 | 14 | const tokenId = { 15 | token_data_id: { 16 | collection: collectionName, 17 | creator, 18 | name: tokenName, 19 | }, 20 | property_version: "1", 21 | }; 22 | 23 | let resources = await client.getAccountResources(account); 24 | const accountResource = resources.find((r) => r.type === tokenStore); 25 | const { handle } = accountResource.data.tokens; 26 | 27 | const getTokenTableItemRequest = { 28 | key_type: "0x3::token::TokenId", 29 | value_type: "0x3::token::Token", 30 | key: tokenId, 31 | }; 32 | 33 | const token = await client.getTableItem(handle, getTokenTableItemRequest); 34 | console.log(JSON.stringify(token)) 35 | })(); 36 | -------------------------------------------------------------------------------- /docs/aptos_whitepaper_by_moveworld.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/icodezjb/learn-move/32bd4d3ff13b482440c0caf2d5f859e72a4883c1/docs/aptos_whitepaper_by_moveworld.pdf -------------------------------------------------------------------------------- /docs/sui_whitepaper_by_moveworld.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/icodezjb/learn-move/32bd4d3ff13b482440c0caf2d5f859e72a4883c1/docs/sui_whitepaper_by_moveworld.pdf -------------------------------------------------------------------------------- /hash_type_and_key/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "anyhow" 7 | version = "1.0.66" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "216261ddc8289130e551ddcd5ce8a064710c0d064a4d2895c67151c92b5443f6" 10 | 11 | [[package]] 12 | name = "arrayvec" 13 | version = "0.7.2" 14 | source = "registry+https://github.com/rust-lang/crates.io-index" 15 | checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" 16 | 17 | [[package]] 18 | name = "autocfg" 19 | version = "1.1.0" 20 | source = "registry+https://github.com/rust-lang/crates.io-index" 21 | checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" 22 | 23 | [[package]] 24 | name = "bcs" 25 | version = "0.1.4" 26 | source = "registry+https://github.com/rust-lang/crates.io-index" 27 | checksum = "8b06b4c1f053002b70e7084ac944c77d58d5d92b2110dbc5e852735e00ad3ccc" 28 | dependencies = [ 29 | "serde", 30 | "thiserror", 31 | ] 32 | 33 | [[package]] 34 | name = "bitvec" 35 | version = "0.20.4" 36 | source = "registry+https://github.com/rust-lang/crates.io-index" 37 | checksum = "7774144344a4faa177370406a7ff5f1da24303817368584c6206c8303eb07848" 38 | dependencies = [ 39 | "funty", 40 | "radium", 41 | "tap", 42 | "wyz", 43 | ] 44 | 45 | [[package]] 46 | name = "block-buffer" 47 | version = "0.10.3" 48 | source = "registry+https://github.com/rust-lang/crates.io-index" 49 | checksum = "69cce20737498f97b993470a6e536b8523f0af7892a4f928cceb1ac5e52ebe7e" 50 | dependencies = [ 51 | "generic-array", 52 | ] 53 | 54 | [[package]] 55 | name = "byte-slice-cast" 56 | version = "1.2.2" 57 | source = "registry+https://github.com/rust-lang/crates.io-index" 58 | checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" 59 | 60 | [[package]] 61 | name = "byteorder" 62 | version = "1.4.3" 63 | source = "registry+https://github.com/rust-lang/crates.io-index" 64 | checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" 65 | 66 | [[package]] 67 | name = "cfg-if" 68 | version = "1.0.0" 69 | source = "registry+https://github.com/rust-lang/crates.io-index" 70 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 71 | 72 | [[package]] 73 | name = "cpufeatures" 74 | version = "0.2.5" 75 | source = "registry+https://github.com/rust-lang/crates.io-index" 76 | checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320" 77 | dependencies = [ 78 | "libc", 79 | ] 80 | 81 | [[package]] 82 | name = "crunchy" 83 | version = "0.2.2" 84 | source = "registry+https://github.com/rust-lang/crates.io-index" 85 | checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" 86 | 87 | [[package]] 88 | name = "crypto-common" 89 | version = "0.1.6" 90 | source = "registry+https://github.com/rust-lang/crates.io-index" 91 | checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" 92 | dependencies = [ 93 | "generic-array", 94 | "typenum", 95 | ] 96 | 97 | [[package]] 98 | name = "digest" 99 | version = "0.10.6" 100 | source = "registry+https://github.com/rust-lang/crates.io-index" 101 | checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" 102 | dependencies = [ 103 | "block-buffer", 104 | "crypto-common", 105 | ] 106 | 107 | [[package]] 108 | name = "ethnum" 109 | version = "1.3.2" 110 | source = "registry+https://github.com/rust-lang/crates.io-index" 111 | checksum = "0198b9d0078e0f30dedc7acbb21c974e838fc8fae3ee170128658a98cb2c1c04" 112 | 113 | [[package]] 114 | name = "fixed-hash" 115 | version = "0.7.0" 116 | source = "registry+https://github.com/rust-lang/crates.io-index" 117 | checksum = "cfcf0ed7fe52a17a03854ec54a9f76d6d84508d1c0e66bc1793301c73fc8493c" 118 | dependencies = [ 119 | "byteorder", 120 | "rand", 121 | "rustc-hex", 122 | "static_assertions", 123 | ] 124 | 125 | [[package]] 126 | name = "funty" 127 | version = "1.1.0" 128 | source = "registry+https://github.com/rust-lang/crates.io-index" 129 | checksum = "fed34cd105917e91daa4da6b3728c47b068749d6a62c59811f06ed2ac71d9da7" 130 | 131 | [[package]] 132 | name = "generic-array" 133 | version = "0.14.6" 134 | source = "registry+https://github.com/rust-lang/crates.io-index" 135 | checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9" 136 | dependencies = [ 137 | "typenum", 138 | "version_check", 139 | ] 140 | 141 | [[package]] 142 | name = "getrandom" 143 | version = "0.2.8" 144 | source = "registry+https://github.com/rust-lang/crates.io-index" 145 | checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" 146 | dependencies = [ 147 | "cfg-if", 148 | "libc", 149 | "wasi", 150 | ] 151 | 152 | [[package]] 153 | name = "hash_type_and_key" 154 | version = "0.1.0" 155 | dependencies = [ 156 | "bcs", 157 | "hex", 158 | "move-core-types", 159 | "move-vm-types", 160 | "sha3", 161 | ] 162 | 163 | [[package]] 164 | name = "hex" 165 | version = "0.4.3" 166 | source = "registry+https://github.com/rust-lang/crates.io-index" 167 | checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" 168 | 169 | [[package]] 170 | name = "impl-codec" 171 | version = "0.5.1" 172 | source = "registry+https://github.com/rust-lang/crates.io-index" 173 | checksum = "161ebdfec3c8e3b52bf61c4f3550a1eea4f9579d10dc1b936f3171ebdcd6c443" 174 | dependencies = [ 175 | "parity-scale-codec", 176 | ] 177 | 178 | [[package]] 179 | name = "impl-serde" 180 | version = "0.3.2" 181 | source = "registry+https://github.com/rust-lang/crates.io-index" 182 | checksum = "4551f042f3438e64dbd6226b20527fc84a6e1fe65688b58746a2f53623f25f5c" 183 | dependencies = [ 184 | "serde", 185 | ] 186 | 187 | [[package]] 188 | name = "impl-trait-for-tuples" 189 | version = "0.2.2" 190 | source = "registry+https://github.com/rust-lang/crates.io-index" 191 | checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb" 192 | dependencies = [ 193 | "proc-macro2", 194 | "quote", 195 | "syn", 196 | ] 197 | 198 | [[package]] 199 | name = "keccak" 200 | version = "0.1.3" 201 | source = "registry+https://github.com/rust-lang/crates.io-index" 202 | checksum = "3afef3b6eff9ce9d8ff9b3601125eec7f0c8cbac7abd14f355d053fa56c98768" 203 | dependencies = [ 204 | "cpufeatures", 205 | ] 206 | 207 | [[package]] 208 | name = "libc" 209 | version = "0.2.138" 210 | source = "registry+https://github.com/rust-lang/crates.io-index" 211 | checksum = "db6d7e329c562c5dfab7a46a2afabc8b987ab9a4834c9d1ca04dc54c1546cef8" 212 | 213 | [[package]] 214 | name = "move-binary-format" 215 | version = "0.0.3" 216 | source = "git+https://github.com/move-language/move?rev=0800fc79a98ca304bd449878f545cdcaff6f94bb#0800fc79a98ca304bd449878f545cdcaff6f94bb" 217 | dependencies = [ 218 | "anyhow", 219 | "move-core-types", 220 | "once_cell", 221 | "ref-cast", 222 | "serde", 223 | "variant_count", 224 | ] 225 | 226 | [[package]] 227 | name = "move-core-types" 228 | version = "0.0.4" 229 | source = "git+https://github.com/move-language/move?rev=0800fc79a98ca304bd449878f545cdcaff6f94bb#0800fc79a98ca304bd449878f545cdcaff6f94bb" 230 | dependencies = [ 231 | "anyhow", 232 | "bcs", 233 | "ethnum", 234 | "hex", 235 | "num", 236 | "once_cell", 237 | "primitive-types", 238 | "rand", 239 | "ref-cast", 240 | "serde", 241 | "serde_bytes", 242 | "uint", 243 | ] 244 | 245 | [[package]] 246 | name = "move-vm-types" 247 | version = "0.1.0" 248 | source = "git+https://github.com/move-language/move?rev=0800fc79a98ca304bd449878f545cdcaff6f94bb#0800fc79a98ca304bd449878f545cdcaff6f94bb" 249 | dependencies = [ 250 | "bcs", 251 | "move-binary-format", 252 | "move-core-types", 253 | "once_cell", 254 | "serde", 255 | "smallvec", 256 | ] 257 | 258 | [[package]] 259 | name = "num" 260 | version = "0.4.0" 261 | source = "registry+https://github.com/rust-lang/crates.io-index" 262 | checksum = "43db66d1170d347f9a065114077f7dccb00c1b9478c89384490a3425279a4606" 263 | dependencies = [ 264 | "num-bigint", 265 | "num-complex", 266 | "num-integer", 267 | "num-iter", 268 | "num-rational", 269 | "num-traits", 270 | ] 271 | 272 | [[package]] 273 | name = "num-bigint" 274 | version = "0.4.3" 275 | source = "registry+https://github.com/rust-lang/crates.io-index" 276 | checksum = "f93ab6289c7b344a8a9f60f88d80aa20032336fe78da341afc91c8a2341fc75f" 277 | dependencies = [ 278 | "autocfg", 279 | "num-integer", 280 | "num-traits", 281 | ] 282 | 283 | [[package]] 284 | name = "num-complex" 285 | version = "0.4.2" 286 | source = "registry+https://github.com/rust-lang/crates.io-index" 287 | checksum = "7ae39348c8bc5fbd7f40c727a9925f03517afd2ab27d46702108b6a7e5414c19" 288 | dependencies = [ 289 | "num-traits", 290 | ] 291 | 292 | [[package]] 293 | name = "num-integer" 294 | version = "0.1.45" 295 | source = "registry+https://github.com/rust-lang/crates.io-index" 296 | checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" 297 | dependencies = [ 298 | "autocfg", 299 | "num-traits", 300 | ] 301 | 302 | [[package]] 303 | name = "num-iter" 304 | version = "0.1.43" 305 | source = "registry+https://github.com/rust-lang/crates.io-index" 306 | checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252" 307 | dependencies = [ 308 | "autocfg", 309 | "num-integer", 310 | "num-traits", 311 | ] 312 | 313 | [[package]] 314 | name = "num-rational" 315 | version = "0.4.1" 316 | source = "registry+https://github.com/rust-lang/crates.io-index" 317 | checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" 318 | dependencies = [ 319 | "autocfg", 320 | "num-bigint", 321 | "num-integer", 322 | "num-traits", 323 | ] 324 | 325 | [[package]] 326 | name = "num-traits" 327 | version = "0.2.15" 328 | source = "registry+https://github.com/rust-lang/crates.io-index" 329 | checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" 330 | dependencies = [ 331 | "autocfg", 332 | ] 333 | 334 | [[package]] 335 | name = "once_cell" 336 | version = "1.16.0" 337 | source = "registry+https://github.com/rust-lang/crates.io-index" 338 | checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860" 339 | 340 | [[package]] 341 | name = "parity-scale-codec" 342 | version = "2.3.1" 343 | source = "registry+https://github.com/rust-lang/crates.io-index" 344 | checksum = "373b1a4c1338d9cd3d1fa53b3a11bdab5ab6bd80a20f7f7becd76953ae2be909" 345 | dependencies = [ 346 | "arrayvec", 347 | "bitvec", 348 | "byte-slice-cast", 349 | "impl-trait-for-tuples", 350 | "parity-scale-codec-derive", 351 | "serde", 352 | ] 353 | 354 | [[package]] 355 | name = "parity-scale-codec-derive" 356 | version = "2.3.1" 357 | source = "registry+https://github.com/rust-lang/crates.io-index" 358 | checksum = "1557010476e0595c9b568d16dcfb81b93cdeb157612726f5170d31aa707bed27" 359 | dependencies = [ 360 | "proc-macro-crate", 361 | "proc-macro2", 362 | "quote", 363 | "syn", 364 | ] 365 | 366 | [[package]] 367 | name = "ppv-lite86" 368 | version = "0.2.17" 369 | source = "registry+https://github.com/rust-lang/crates.io-index" 370 | checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" 371 | 372 | [[package]] 373 | name = "primitive-types" 374 | version = "0.10.1" 375 | source = "registry+https://github.com/rust-lang/crates.io-index" 376 | checksum = "05e4722c697a58a99d5d06a08c30821d7c082a4632198de1eaa5a6c22ef42373" 377 | dependencies = [ 378 | "fixed-hash", 379 | "impl-codec", 380 | "impl-serde", 381 | "uint", 382 | ] 383 | 384 | [[package]] 385 | name = "proc-macro-crate" 386 | version = "1.1.3" 387 | source = "registry+https://github.com/rust-lang/crates.io-index" 388 | checksum = "e17d47ce914bf4de440332250b0edd23ce48c005f59fab39d3335866b114f11a" 389 | dependencies = [ 390 | "thiserror", 391 | "toml", 392 | ] 393 | 394 | [[package]] 395 | name = "proc-macro2" 396 | version = "1.0.47" 397 | source = "registry+https://github.com/rust-lang/crates.io-index" 398 | checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725" 399 | dependencies = [ 400 | "unicode-ident", 401 | ] 402 | 403 | [[package]] 404 | name = "quote" 405 | version = "1.0.21" 406 | source = "registry+https://github.com/rust-lang/crates.io-index" 407 | checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" 408 | dependencies = [ 409 | "proc-macro2", 410 | ] 411 | 412 | [[package]] 413 | name = "radium" 414 | version = "0.6.2" 415 | source = "registry+https://github.com/rust-lang/crates.io-index" 416 | checksum = "643f8f41a8ebc4c5dc4515c82bb8abd397b527fc20fd681b7c011c2aee5d44fb" 417 | 418 | [[package]] 419 | name = "rand" 420 | version = "0.8.5" 421 | source = "registry+https://github.com/rust-lang/crates.io-index" 422 | checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" 423 | dependencies = [ 424 | "libc", 425 | "rand_chacha", 426 | "rand_core", 427 | ] 428 | 429 | [[package]] 430 | name = "rand_chacha" 431 | version = "0.3.1" 432 | source = "registry+https://github.com/rust-lang/crates.io-index" 433 | checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" 434 | dependencies = [ 435 | "ppv-lite86", 436 | "rand_core", 437 | ] 438 | 439 | [[package]] 440 | name = "rand_core" 441 | version = "0.6.4" 442 | source = "registry+https://github.com/rust-lang/crates.io-index" 443 | checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" 444 | dependencies = [ 445 | "getrandom", 446 | ] 447 | 448 | [[package]] 449 | name = "ref-cast" 450 | version = "1.0.13" 451 | source = "registry+https://github.com/rust-lang/crates.io-index" 452 | checksum = "53b15debb4f9d60d767cd8ca9ef7abb2452922f3214671ff052defc7f3502c44" 453 | dependencies = [ 454 | "ref-cast-impl", 455 | ] 456 | 457 | [[package]] 458 | name = "ref-cast-impl" 459 | version = "1.0.13" 460 | source = "registry+https://github.com/rust-lang/crates.io-index" 461 | checksum = "abfa8511e9e94fd3de6585a3d3cd00e01ed556dc9814829280af0e8dc72a8f36" 462 | dependencies = [ 463 | "proc-macro2", 464 | "quote", 465 | "syn", 466 | ] 467 | 468 | [[package]] 469 | name = "rustc-hex" 470 | version = "2.1.0" 471 | source = "registry+https://github.com/rust-lang/crates.io-index" 472 | checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" 473 | 474 | [[package]] 475 | name = "serde" 476 | version = "1.0.149" 477 | source = "registry+https://github.com/rust-lang/crates.io-index" 478 | checksum = "256b9932320c590e707b94576e3cc1f7c9024d0ee6612dfbcf1cb106cbe8e055" 479 | dependencies = [ 480 | "serde_derive", 481 | ] 482 | 483 | [[package]] 484 | name = "serde_bytes" 485 | version = "0.11.7" 486 | source = "registry+https://github.com/rust-lang/crates.io-index" 487 | checksum = "cfc50e8183eeeb6178dcb167ae34a8051d63535023ae38b5d8d12beae193d37b" 488 | dependencies = [ 489 | "serde", 490 | ] 491 | 492 | [[package]] 493 | name = "serde_derive" 494 | version = "1.0.149" 495 | source = "registry+https://github.com/rust-lang/crates.io-index" 496 | checksum = "b4eae9b04cbffdfd550eb462ed33bc6a1b68c935127d008b27444d08380f94e4" 497 | dependencies = [ 498 | "proc-macro2", 499 | "quote", 500 | "syn", 501 | ] 502 | 503 | [[package]] 504 | name = "sha3" 505 | version = "0.10.6" 506 | source = "registry+https://github.com/rust-lang/crates.io-index" 507 | checksum = "bdf0c33fae925bdc080598b84bc15c55e7b9a4a43b3c704da051f977469691c9" 508 | dependencies = [ 509 | "digest", 510 | "keccak", 511 | ] 512 | 513 | [[package]] 514 | name = "smallvec" 515 | version = "1.10.0" 516 | source = "registry+https://github.com/rust-lang/crates.io-index" 517 | checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" 518 | 519 | [[package]] 520 | name = "static_assertions" 521 | version = "1.1.0" 522 | source = "registry+https://github.com/rust-lang/crates.io-index" 523 | checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" 524 | 525 | [[package]] 526 | name = "syn" 527 | version = "1.0.105" 528 | source = "registry+https://github.com/rust-lang/crates.io-index" 529 | checksum = "60b9b43d45702de4c839cb9b51d9f529c5dd26a4aff255b42b1ebc03e88ee908" 530 | dependencies = [ 531 | "proc-macro2", 532 | "quote", 533 | "unicode-ident", 534 | ] 535 | 536 | [[package]] 537 | name = "tap" 538 | version = "1.0.1" 539 | source = "registry+https://github.com/rust-lang/crates.io-index" 540 | checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" 541 | 542 | [[package]] 543 | name = "thiserror" 544 | version = "1.0.37" 545 | source = "registry+https://github.com/rust-lang/crates.io-index" 546 | checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e" 547 | dependencies = [ 548 | "thiserror-impl", 549 | ] 550 | 551 | [[package]] 552 | name = "thiserror-impl" 553 | version = "1.0.37" 554 | source = "registry+https://github.com/rust-lang/crates.io-index" 555 | checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb" 556 | dependencies = [ 557 | "proc-macro2", 558 | "quote", 559 | "syn", 560 | ] 561 | 562 | [[package]] 563 | name = "toml" 564 | version = "0.5.9" 565 | source = "registry+https://github.com/rust-lang/crates.io-index" 566 | checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7" 567 | dependencies = [ 568 | "serde", 569 | ] 570 | 571 | [[package]] 572 | name = "typenum" 573 | version = "1.15.0" 574 | source = "registry+https://github.com/rust-lang/crates.io-index" 575 | checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" 576 | 577 | [[package]] 578 | name = "uint" 579 | version = "0.9.5" 580 | source = "registry+https://github.com/rust-lang/crates.io-index" 581 | checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" 582 | dependencies = [ 583 | "byteorder", 584 | "crunchy", 585 | "hex", 586 | "static_assertions", 587 | ] 588 | 589 | [[package]] 590 | name = "unicode-ident" 591 | version = "1.0.5" 592 | source = "registry+https://github.com/rust-lang/crates.io-index" 593 | checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" 594 | 595 | [[package]] 596 | name = "variant_count" 597 | version = "1.1.0" 598 | source = "registry+https://github.com/rust-lang/crates.io-index" 599 | checksum = "aae2faf80ac463422992abf4de234731279c058aaf33171ca70277c98406b124" 600 | dependencies = [ 601 | "quote", 602 | "syn", 603 | ] 604 | 605 | [[package]] 606 | name = "version_check" 607 | version = "0.9.4" 608 | source = "registry+https://github.com/rust-lang/crates.io-index" 609 | checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" 610 | 611 | [[package]] 612 | name = "wasi" 613 | version = "0.11.0+wasi-snapshot-preview1" 614 | source = "registry+https://github.com/rust-lang/crates.io-index" 615 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 616 | 617 | [[package]] 618 | name = "wyz" 619 | version = "0.2.0" 620 | source = "registry+https://github.com/rust-lang/crates.io-index" 621 | checksum = "85e60b0d1b5f99db2556934e21937020776a5d31520bf169e851ac44e6420214" 622 | -------------------------------------------------------------------------------- /hash_type_and_key/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "hash_type_and_key" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [workspace.dependencies] 9 | move-core-types = { git = "https://github.com/move-language/move", rev = "0800fc79a98ca304bd449878f545cdcaff6f94bb", features = ["address20"] } 10 | move-vm-types = { git = "https://github.com/move-language/move", rev = "0800fc79a98ca304bd449878f545cdcaff6f94bb" } 11 | 12 | [dependencies] 13 | bcs = "0.1.4" 14 | hex = "0.4.3" 15 | sha3 = "0.10.6" 16 | move-core-types.workspace = true 17 | move-vm-types.workspace = true 18 | -------------------------------------------------------------------------------- /hash_type_and_key/README.md: -------------------------------------------------------------------------------- 1 | # 链下计算table和object_table的key 2 | 3 | ### 1. 为什么需要链下计算key? 4 | sui的table和object_table适合存储大量数据, 但链下取值的时候需要用 5 | getObjectsOwnedByObject先取得所有的keys, 这一步受限于rpc server(最大返回 10MB数据). 6 | 如果能在链下计算出keys, 就不需要查询rpc server了. 也就是用"计算key"替代"查询key". 7 | 8 | 9 | ### 2. hash_type_and_key 10 | table和object_table都用到了 [hash_type_and_key](https://github.com/MystenLabs/sui/blob/main/crates/sui-framework/src/natives/dynamic_field.rs#L52-L107) 来生成key 11 | 12 | `hash_type_and_key`的参数是table_id,key的类型和值, 13 | 主要操作就是对table_id,key的值和key的StructTag进行Sha3_256 hash 14 | 15 | ```rust 16 | // native fun hash_type_and_key(parent: address, k: K): address; 17 | pub fn hash_type_and_key( 18 | context: &mut NativeContext, 19 | mut ty_args: Vec, 20 | mut args: VecDeque, 21 | ) -> PartialVMResult { 22 | assert!(ty_args.len() == 1); 23 | assert!(args.len() == 2); 24 | let k_ty = ty_args.pop().unwrap(); 25 | let k: Value = args.pop_back().unwrap(); 26 | let parent: SuiAddress = pop_arg!(args, AccountAddress).into(); 27 | let k_tag = context.type_to_type_tag(&k_ty)?; 28 | // build bytes 29 | let k_tag_bytes = match bcs::to_bytes(&k_tag) { 30 | Ok(bytes) => bytes, 31 | Err(_) => { 32 | return Ok(NativeResult::err( 33 | legacy_emit_cost(), 34 | E_BCS_SERIALIZATION_FAILURE, 35 | )); 36 | } 37 | }; 38 | let k_layout = match context.type_to_type_layout(&k_ty) { 39 | Ok(Some(layout)) => layout, 40 | _ => { 41 | return Ok(NativeResult::err( 42 | legacy_emit_cost(), 43 | E_BCS_SERIALIZATION_FAILURE, 44 | )) 45 | } 46 | }; 47 | let k_bytes = match k.simple_serialize(&k_layout) { 48 | Some(bytes) => bytes, 49 | None => { 50 | return Ok(NativeResult::err( 51 | legacy_emit_cost(), 52 | E_BCS_SERIALIZATION_FAILURE, 53 | )) 54 | } 55 | }; 56 | // hash(parent || k || K) 57 | let mut hasher = Sha3_256::default(); 58 | hasher.update(parent); 59 | hasher.update(k_bytes); 60 | hasher.update(k_tag_bytes); 61 | let hash = hasher.finalize(); 62 | 63 | // truncate into an ObjectID and return 64 | // OK to access slice because Sha3_256 should never be shorter than ObjectID::LENGTH. 65 | let id = ObjectID::try_from(&hash.as_ref()[0..ObjectID::LENGTH]).unwrap(); 66 | 67 | Ok(NativeResult::ok( 68 | legacy_emit_cost(), 69 | smallvec![Value::address(id.into())], 70 | )) 71 | } 72 | ``` 73 | 74 | ### 3. 最佳实践 75 | 用`u32`,`u64`等无符号整数做为`table`或`object_table`的`key` 76 | 77 | -------------------------------------------------------------------------------- /hash_type_and_key/src/main.rs: -------------------------------------------------------------------------------- 1 | use std::str::FromStr; 2 | 3 | use move_core_types::{ 4 | account_address::AccountAddress, 5 | identifier::Identifier, 6 | language_storage::{StructTag, TypeTag}, 7 | value::{MoveStructLayout, MoveTypeLayout}, 8 | }; 9 | use move_vm_types::{values::{Struct, Value}}; 10 | use sha3::{Digest, Sha3_256}; 11 | 12 | fn main() { 13 | for_object_table_first_key("0xa236bdcab2880a9c7d5ef9974796bd4126c52eef"); 14 | 15 | for_table_first_key("0x03c8e4462dfb7deecabb5af3dc6e95a02619ebae"); 16 | } 17 | 18 | fn for_object_table_first_key(table_id: &str) { 19 | let struct_tag = StructTag { 20 | address: AccountAddress::from_hex_literal("0x0000000000000000000000000000000000000002").unwrap(), 21 | module: Identifier::from_str("dynamic_object_field").unwrap(), 22 | name: Identifier::from_str("Wrapper").unwrap(), 23 | type_params: vec![TypeTag::U64], 24 | }; 25 | 26 | let wrapper_u64_tag = TypeTag::Struct(struct_tag.clone()); 27 | let wrapper_u64_tag_bytes = bcs::to_bytes(&wrapper_u64_tag).unwrap(); 28 | // println!("{:?}", wrapper_u64_tag_bytes); 29 | let expect = [ 30 | 7u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 20, 31 | 100, 121, 110, 97, 109, 105, 99, 95, 111, 98, 106, 101, 99, 116, 95, 32 | 102, 105, 101, 108, 100, 7, 87, 114, 97, 112, 112, 101, 114, 1, 2].to_vec(); 33 | assert_eq!(expect, wrapper_u64_tag_bytes); 34 | 35 | let wrapper_u64_layout = MoveTypeLayout::Struct( 36 | MoveStructLayout::Runtime { 37 | 0: vec![MoveTypeLayout::U64] 38 | } 39 | ); 40 | 41 | let wrapper_u64_value = Value::struct_(Struct::pack([Value::u64(0)])); 42 | let wrapper_u64_value_bytes = wrapper_u64_value.simple_serialize(&wrapper_u64_layout).unwrap(); 43 | // println!("{:?}", wrapper_u64_value_bytes); 44 | assert_eq!(wrapper_u64_value_bytes, [0, 0, 0, 0, 0, 0, 0, 0]); 45 | 46 | let table_id = AccountAddress::from_hex_literal(table_id).unwrap(); 47 | 48 | let mut hasher = Sha3_256::new(); 49 | hasher.update(table_id); 50 | hasher.update(wrapper_u64_value_bytes); 51 | hasher.update(wrapper_u64_tag_bytes); 52 | let hash = hasher.finalize(); 53 | let first_key = format!("0x{}", hex::encode(hash[..20].to_vec())); 54 | 55 | // println!("{:?}", first_key); 56 | assert_eq!("0xdf50efa50e58c86d8417095299c0c7cbec92deb7", first_key); 57 | } 58 | 59 | fn for_table_first_key(table_id: &str) { 60 | let u64_tag = TypeTag::U64; 61 | let u64_tag_bytes = bcs::to_bytes(&u64_tag).unwrap(); 62 | // println!("{:?}", u64_tag_bytes); 63 | assert_eq!(u64_tag_bytes, [2]); 64 | 65 | let u64_value = Value::u64(0); 66 | let u64_value_bytes = u64_value.simple_serialize(&MoveTypeLayout::U64).unwrap(); 67 | // println!("{:?}", u64_value_bytes); 68 | assert_eq!(u64_value_bytes, [0, 0, 0, 0, 0, 0, 0, 0]); 69 | 70 | let table_id = AccountAddress::from_hex_literal(table_id).unwrap(); 71 | 72 | let mut hasher = Sha3_256::new(); 73 | hasher.update(table_id); 74 | hasher.update(u64_value_bytes); 75 | hasher.update(u64_tag_bytes); 76 | let hash = hasher.finalize(); 77 | let first_key = format!("0x{}", hex::encode(hash[..20].to_vec())); 78 | 79 | // println!("{:?}", first_key); 80 | assert_eq!("0xb55d2a87319747315615cb05a62d1b59307c832e", first_key); 81 | } 82 | -------------------------------------------------------------------------------- /multisig-transaction/README.md: -------------------------------------------------------------------------------- 1 | # Multisig transfer coin transaction 2 | 3 | ## intro 4 | - `multisign_create`: create a multisig address 5 | ```bash 6 | node src/multisign_create.js -h 7 | Usage: multisign_create [options] 8 | 9 | Options: 10 | -p, --pubkey specify ed25519 pubkeys(MAX=32) 11 | -t, --threshold specify the threshold of multi-sign address 12 | -h, --help display help for command 13 | 14 | ``` 15 | 16 | - `multisign_transfer`: transfer coin by single sign 17 | ```bash 18 | node src/multisign_transfer.js -h 19 | Usage: multisign_transfer [options] 20 | 21 | Options: 22 | -m, --multi_address the sender of the coin 23 | -r, --receiver the receiver of the coin 24 | -a, --amount the amount of the coin 25 | --coin the coin type (default: "0x1::aptos_coin::AptosCoin") 26 | --private_key the privkey for single sign 27 | --url the url to a fullnode on the network 28 | --chain_id the chain id, use query if url set 29 | --sequence the sequence number, use query if url set 30 | --max_gas the max gas for this transaction (default: "1000") 31 | --expiration transaction is discarded if it is not executed before expiration timestamp 32 | -h, --help display help for command 33 | ``` 34 | 35 | - `multisign_commit`: commit multisig transaction to aptos blockchain 36 | ```bash 37 | node src/multisign_commit.js -h 38 | Usage: multisign_commit [options] 39 | 40 | Options: 41 | -r, --raw_tx the raw transaction 42 | -s, --signatures the signatures of this raw transaction 43 | -b, --bitmap the bitmap of this transaction in ascending order. eg. [0 3 31] 44 | -u, --url the url to a fullnode on the network 45 | -p, --public_key the multi sign public key 46 | --dry_run only dry run not commit (default: false) 47 | -h, --help display help for command 48 | ``` 49 | 50 | - `multisign_register`: register coin for multisig address 51 | ```bash 52 | node src/multisign_register.js -h 53 | Usage: multisign_register [options] 54 | 55 | Options: 56 | -m, --multi_address the sender of the coin 57 | --coin the coin type (default: "0x1::aptos_coin::AptosCoin") 58 | --private_key the privkey for single sign 59 | --url the url to a fullnode on the network 60 | --chain_id the chain id, use query if url set 61 | --sequence the sequence number, use query if url set 62 | --max_gas the max gas for this transaction (default: "1000") 63 | --expiration transaction is discarded if it is not executed before expiration timestamp 64 | -h, --help display help for command 65 | ``` 66 | 67 | ## precondition for this example (2-of-3 multisig) 68 | - [aptos-cli](https://github.com/aptos-labs/aptos-core/releases) 69 | - run `yarn install` 70 | - account1 71 | ```txt 72 | private_key: "0x1d5c699949317f8b41f31ddff29332943b1c31dd916e1b6747f408852e25f16f" 73 | public_key: "0x027b9579c66cbfae60651b7c5f41fcb65eff5e229f29503f17f1eb0780981b89" 74 | account: d02617efb7147fc1b313d6a6feadef2fc5b21e38268cea50f51ec2222ae64a2f 75 | ``` 76 | - account2 77 | ```txt 78 | private_key: "0xc43f88efcf5b14dc9ba00f3d73e8a455df260e730133fcd81386df1d463d0332" 79 | public_key: "0x9a6c8012d9ac973e976cb85d15f611da4f32f95cf0f55e9bf7e03c2fc347bcd1" 80 | account: 2e39b3b448114792d41ea4ee26f536595a001f734f94b5bd56ae3de6c3096cb0 81 | ``` 82 | - account3 83 | ```txt 84 | private_key: "0x9abfcb4278b1830dc5a0997308ab432a307e42b700f47a374b9ea443e94d5e71" 85 | public_key: "0xc7d786d56687362612ae0555ae8e3318698f4641bd0f74a6b69608b027acd672" 86 | account: 1c17d35dc60bfedc67ab25a7967a8153368f072bb5331016894b7d9d455e8dbd 87 | ``` 88 | 89 | ## create a multi-ed25519 account 90 | ```bash 91 | node src/multisign_create.js \ 92 | -p 0x027b9579c66cbfae60651b7c5f41fcb65eff5e229f29503f17f1eb0780981b89 \ 93 | 0x9a6c8012d9ac973e976cb85d15f611da4f32f95cf0f55e9bf7e03c2fc347bcd1 \ 94 | 0xc7d786d56687362612ae0555ae8e3318698f4641bd0f74a6b69608b027acd672 \ 95 | -t 2 96 | 97 | ---------- 2 -of- 3 Multi-Sign----- 98 | PubKey 0 : 0x027b9579c66cbfae60651b7c5f41fcb65eff5e229f29503f17f1eb0780981b89 99 | PubKey 1 : 0x9a6c8012d9ac973e976cb85d15f611da4f32f95cf0f55e9bf7e03c2fc347bcd1 100 | PubKey 2 : 0xc7d786d56687362612ae0555ae8e3318698f4641bd0f74a6b69608b027acd672 101 | Multi-Sign AuthKey: 0x62f8da1b73daf749cab1622f4447be56e2f5e42cfd41f000b68f8f01695d4f54 102 | Multi-Sign Address: 0x62f8da1b73daf749cab1622f4447be56e2f5e42cfd41f000b68f8f01695d4f54 103 | Multi-Sign Pubkey : 0x61027b9579c66cbfae60651b7c5f41fcb65eff5e229f29503f17f1eb0780981b899a6c8012d9ac973e976cb85d15f611da4f32f95cf0f55e9bf7e03c2fc347bcd1c7d786d56687362612ae0555ae8e3318698f4641bd0f74a6b69608b027acd67202 104 | ---------- 2 -of- 3 Multi-Sign----- 105 | ``` 106 | `bitmap`: 107 | - `0`: account1 `0xd02617efb7147fc1b313d6a6feadef2fc5b21e38268cea50f51ec2222ae64a2f` 108 | - `1`: account2 `0x2e39b3b448114792d41ea4ee26f536595a001f734f94b5bd56ae3de6c3096cb0` 109 | - `2`: account3 `0x1c17d35dc60bfedc67ab25a7967a8153368f072bb5331016894b7d9d455e8dbd` 110 | 111 | 112 | ## fund multi-ed25519 account 113 | 114 | transfer some `APT` to `multisig-address`: `0x62f8da1b73daf749cab1622f4447be56e2f5e42cfd41f000b68f8f01695d4f54` 115 | 116 | query balance 117 | ```bash 118 | aptos account list --query balance \ 119 | --url https://fullnode.devnet.aptoslabs.com/v1 \ 120 | --account 0x62f8da1b73daf749cab1622f4447be56e2f5e42cfd41f000b68f8f01695d4f54 121 | { 122 | "Result": [ 123 | { 124 | "coin": { 125 | "value": "100000" 126 | }, 127 | "deposit_events": { 128 | "counter": "1", 129 | "guid": { 130 | "id": { 131 | "addr": "0x62f8da1b73daf749cab1622f4447be56e2f5e42cfd41f000b68f8f01695d4f54", 132 | "creation_num": "2" 133 | } 134 | } 135 | }, 136 | "frozen": false, 137 | "withdraw_events": { 138 | "counter": "0", 139 | "guid": { 140 | "id": { 141 | "addr": "0x62f8da1b73daf749cab1622f4447be56e2f5e42cfd41f000b68f8f01695d4f54", 142 | "creation_num": "3" 143 | } 144 | } 145 | } 146 | } 147 | ] 148 | } 149 | 150 | ``` 151 | 152 | ## build multi-ed25519 tx 153 | make a transtion: transfer 1000 APT from `multisig-address` to `0xa24881e004fdbc5550932bb2879129351c21432f21f32d94bf11603bebd9f5c0` 154 | 155 | account3 first sign, account1 second sign 156 | - account3 sign 157 | ```bash 158 | node src/multisign_transfer.js \ 159 | -m 0x62f8da1b73daf749cab1622f4447be56e2f5e42cfd41f000b68f8f01695d4f54 \ 160 | -r 0xa24881e004fdbc5550932bb2879129351c21432f21f32d94bf11603bebd9f5c0 \ 161 | -a 1000 \ 162 | --private_key 0x9abfcb4278b1830dc5a0997308ab432a307e42b700f47a374b9ea443e94d5e71 \ 163 | --url https://fullnode.devnet.aptoslabs.com/v1 164 | 165 | query chain_id and sequence from the fullnode: 166 | fullnode url: https://fullnode.devnet.aptoslabs.com/v1 167 | 168 | ------- 0x1c17d35dc60bfedc67ab25a7967a8153368f072bb5331016894b7d9d455e8dbd build------- 169 | 170 | =========multi sign transfer========== 171 | Multi-Address: 0x62f8da1b73daf749cab1622f4447be56e2f5e42cfd41f000b68f8f01695d4f54 172 | Send Coin : 0x1::aptos_coin::AptosCoin 173 | Receiver : 0xa24881e004fdbc5550932bb2879129351c21432f21f32d94bf11603bebd9f5c0 174 | Amount : 1000 175 | Expiration : 1662609215 (2022-09-08T03:53:35) 176 | Sequence : 0 177 | Chain Id : 25 178 | Max gas : 1000 179 | =========multi sign transfer========== 180 | 181 | Raw Transaction(BCS): 0x62f8da1b73daf749cab1622f4447be56e2f5e42cfd41f000b68f8f01695d4f54000000000000000002000000000000000000000000000000000000000000000000000000000000000104636f696e087472616e73666572010700000000000000000000000000000000000000000000000000000000000000010a6170746f735f636f696e094170746f73436f696e000220a24881e004fdbc5550932bb2879129351c21432f21f32d94bf11603bebd9f5c008e803000000000000e80300000000000001000000000000003f6719630000000019 182 | 183 | single_signature: 0x91a6b981021abdfb4a1bf3bbf780de1622896857b2f15ef78956aab2e0c1be3177f56d9fa4f65086aed4aadb3fedd2b3b68f4e41746c554ee0b61fe2a35c3101 184 | 185 | ``` 186 | 187 | raw transaction: `0x62f8da1b73daf749cab1622f4447be56e2f5e42cfd41f000b68f8f01695d4f54000000000000000002000000000000000000000000000000000000000000000000000000000000000104636f696e087472616e73666572010700000000000000000000000000000000000000000000000000000000000000010a6170746f735f636f696e094170746f73436f696e000220a24881e004fdbc5550932bb2879129351c21432f21f32d94bf11603bebd9f5c008e803000000000000e80300000000000001000000000000003f6719630000000019` 188 | 189 | account3 signature: `0x91a6b981021abdfb4a1bf3bbf780de1622896857b2f15ef78956aab2e0c1be3177f56d9fa4f65086aed4aadb3fedd2b3b68f4e41746c554ee0b61fe2a35c3101` 190 | 191 | - account1 sign 192 | 193 | see the account3 sign info, use `--chain_id`,`--sequence` and `expiration` 194 | 195 | make the raw transaction same as account3 196 | 197 | ```bash 198 | node src/multisign_transfer.js \ 199 | -m 0x62f8da1b73daf749cab1622f4447be56e2f5e42cfd41f000b68f8f01695d4f54 \ 200 | -r 0xa24881e004fdbc5550932bb2879129351c21432f21f32d94bf11603bebd9f5c0 \ 201 | -a 1000 \ 202 | --chain_id 25 \ 203 | --sequence 0 \ 204 | --expiration 1662609215 \ 205 | --private_key 0x1d5c699949317f8b41f31ddff29332943b1c31dd916e1b6747f408852e25f16f 206 | 207 | ------- 0xd02617efb7147fc1b313d6a6feadef2fc5b21e38268cea50f51ec2222ae64a2f build------- 208 | 209 | =========multi sign transfer========== 210 | Multi-Address: 0x62f8da1b73daf749cab1622f4447be56e2f5e42cfd41f000b68f8f01695d4f54 211 | Send Coin : 0x1::aptos_coin::AptosCoin 212 | Receiver : 0xa24881e004fdbc5550932bb2879129351c21432f21f32d94bf11603bebd9f5c0 213 | Amount : 1000 214 | Expiration : 1662609215 (2022-09-08T03:53:35) 215 | Sequence : 0 216 | Chain Id : 25 217 | Max gas : 1000 218 | =========multi sign transfer========== 219 | 220 | Raw Transaction(BCS): 0x62f8da1b73daf749cab1622f4447be56e2f5e42cfd41f000b68f8f01695d4f54000000000000000002000000000000000000000000000000000000000000000000000000000000000104636f696e087472616e73666572010700000000000000000000000000000000000000000000000000000000000000010a6170746f735f636f696e094170746f73436f696e000220a24881e004fdbc5550932bb2879129351c21432f21f32d94bf11603bebd9f5c008e803000000000000e80300000000000001000000000000003f6719630000000019 221 | 222 | single_signature: 0x46afc0a10e1263dfea57c70bc3e482d9fa3f98abeb7406bab8e9b8180190d7619bf9c77730f14c2d1cfdda8b53548699498ff421091c46aa22ea6d9afba55208 223 | 224 | ``` 225 | raw transaction: `0x62f8da1b73daf749cab1622f4447be56e2f5e42cfd41f000b68f8f01695d4f54000000000000000002000000000000000000000000000000000000000000000000000000000000000104636f696e087472616e73666572010700000000000000000000000000000000000000000000000000000000000000010a6170746f735f636f696e094170746f73436f696e000220a24881e004fdbc5550932bb2879129351c21432f21f32d94bf11603bebd9f5c008e803000000000000e80300000000000001000000000000003f6719630000000019` 226 | 227 | account1 signature: `0x46afc0a10e1263dfea57c70bc3e482d9fa3f98abeb7406bab8e9b8180190d7619bf9c77730f14c2d1cfdda8b53548699498ff421091c46aa22ea6d9afba55208` 228 | 229 | 230 | ## commit multi-ed25519 tx 231 | 232 | Use the bitmap is `[0 2]`, the signatures is 233 | ```txt 234 | account1: 0x46afc0a10e1263dfea57c70bc3e482d9fa3f98abeb7406bab8e9b8180190d7619bf9c77730f14c2d1cfdda8b53548699498ff421091c46aa22ea6d9afba55208 235 | 236 | account2: 0x91a6b981021abdfb4a1bf3bbf780de1622896857b2f15ef78956aab2e0c1be3177f56d9fa4f65086aed4aadb3fedd2b3b68f4e41746c554ee0b61fe2a35c3101 237 | ``` 238 | 239 | [bitmap `[2 0]` will fail](https://github.com/aptos-labs/aptos-core/blob/main/crates/aptos-crypto/src/unit_tests/multi_ed25519_test.rs#L353-L362) 240 | 241 | ```bash 242 | $ node src/multisign_commit.js \ 243 | -r 0x62f8da1b73daf749cab1622f4447be56e2f5e42cfd41f000b68f8f01695d4f54000000000000000002000000000000000000000000000000000000000000000000000000000000000104636f696e087472616e73666572010700000000000000000000000000000000000000000000000000000000000000010a6170746f735f636f696e094170746f73436f696e000220a24881e004fdbc5550932bb2879129351c21432f21f32d94bf11603bebd9f5c008e803000000000000e80300000000000001000000000000003f6719630000000019 \ 244 | -s 0x46afc0a10e1263dfea57c70bc3e482d9fa3f98abeb7406bab8e9b8180190d7619bf9c77730f14c2d1cfdda8b53548699498ff421091c46aa22ea6d9afba55208 \ 245 | 0x91a6b981021abdfb4a1bf3bbf780de1622896857b2f15ef78956aab2e0c1be3177f56d9fa4f65086aed4aadb3fedd2b3b68f4e41746c554ee0b61fe2a35c3101 \ 246 | -b 0 2 \ 247 | -u https://fullnode.devnet.aptoslabs.com/v1 \ 248 | -p 0x61027b9579c66cbfae60651b7c5f41fcb65eff5e229f29503f17f1eb0780981b899a6c8012d9ac973e976cb85d15f611da4f32f95cf0f55e9bf7e03c2fc347bcd1c7d786d56687362612ae0555ae8e3318698f4641bd0f74a6b69608b027acd67202 249 | 250 | =========bitmap========== 251 | bitmap: [ 0, 2 ] 252 | =========bitmap========== 253 | 254 | =========multi sign transfer========== 255 | Multi-Address: 0x62f8da1b73daf749cab1622f4447be56e2f5e42cfd41f000b68f8f01695d4f54 256 | Send Coin : 0x1::aptos_coin::AptosCoin 257 | Receiver : 0xa24881e004fdbc5550932bb2879129351c21432f21f32d94bf11603bebd9f5c0 258 | Amount : 1000 259 | Expiration : 1662609215 (2022-09-08T03:53:35) 260 | Sequence : 0 261 | Chain Id : 25 262 | Max gas : 1000 263 | =========multi sign transfer========== 264 | 265 | 266 | Multisig Tx hash: 0x9ef5d95c8df8ef1d563ac34f0a2054085cc633f912a7b121c36843267eb69a7a 267 | 268 | ``` 269 | 270 | the multisig transaction info 271 | ```txt 272 | { 273 | version: '77925281', 274 | hash: '0x9ef5d95c8df8ef1d563ac34f0a2054085cc633f912a7b121c36843267eb69a7a', 275 | state_change_hash: '0x6cb470baaa2b1329211230420951149b1e982be18ad60172e72efef0bac8339e', 276 | event_root_hash: '0xb356b99412b16b2cf04920c7932f439651ba06f76f9a5f0ae310f9a50532f120', 277 | state_checkpoint_hash: null, 278 | gas_used: '51', 279 | success: true, 280 | vm_status: 'Executed successfully', 281 | accumulator_root_hash: '0x3717573f05ad241373d6d5e28d15cf0492cdde5a47f9626ec0e0b33cde060a37', 282 | changes: [ 283 | { 284 | address: '0x62f8da1b73daf749cab1622f4447be56e2f5e42cfd41f000b68f8f01695d4f54', 285 | state_key_hash: '0x627f24db005f57a82aed956e50ad943efe69cde7172fe7ee2aae63a2d6cdda31', 286 | data: [Object], 287 | type: 'write_resource' 288 | }, 289 | { 290 | address: '0x62f8da1b73daf749cab1622f4447be56e2f5e42cfd41f000b68f8f01695d4f54', 291 | state_key_hash: '0xb43a7ba20464181eb70e690be84cffdcd48d77677d317d884c09a3607308ae67', 292 | data: [Object], 293 | type: 'write_resource' 294 | }, 295 | { 296 | address: '0xa24881e004fdbc5550932bb2879129351c21432f21f32d94bf11603bebd9f5c0', 297 | state_key_hash: '0xaf3d556ae274c6c2d759cd269eaa751c237c9009d59b708fcd6eea67d8549263', 298 | data: [Object], 299 | type: 'write_resource' 300 | }, 301 | { 302 | state_key_hash: '0x6e4b28d40f98a106a65163530924c0dcb40c1349d3aa915d108b4d6cfc1ddb19', 303 | handle: '0x1b854694ae746cdbd8d44186ca4929b2b337df21d1c74633be19b2710552fdca', 304 | key: '0x0619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935', 305 | value: '0x12a017c3b10409000100000000000000', 306 | data: null, 307 | type: 'write_table_item' 308 | } 309 | ], 310 | sender: '0x62f8da1b73daf749cab1622f4447be56e2f5e42cfd41f000b68f8f01695d4f54', 311 | sequence_number: '0', 312 | max_gas_amount: '1000', 313 | gas_unit_price: '1', 314 | expiration_timestamp_secs: '1662609215', 315 | payload: { 316 | function: '0x1::coin::transfer', 317 | type_arguments: [ '0x1::aptos_coin::AptosCoin' ], 318 | arguments: [ 319 | '0xa24881e004fdbc5550932bb2879129351c21432f21f32d94bf11603bebd9f5c0', 320 | '1000' 321 | ], 322 | type: 'entry_function_payload' 323 | }, 324 | signature: { 325 | public_keys: [ 326 | '0x027b9579c66cbfae60651b7c5f41fcb65eff5e229f29503f17f1eb0780981b89', 327 | '0x9a6c8012d9ac973e976cb85d15f611da4f32f95cf0f55e9bf7e03c2fc347bcd1', 328 | '0xc7d786d56687362612ae0555ae8e3318698f4641bd0f74a6b69608b027acd672' 329 | ], 330 | signatures: [ 331 | '0x46afc0a10e1263dfea57c70bc3e482d9fa3f98abeb7406bab8e9b8180190d7619bf9c77730f14c2d1cfdda8b53548699498ff421091c46aa22ea6d9afba55208', 332 | '0x91a6b981021abdfb4a1bf3bbf780de1622896857b2f15ef78956aab2e0c1be3177f56d9fa4f65086aed4aadb3fedd2b3b68f4e41746c554ee0b61fe2a35c3101' 333 | ], 334 | threshold: 2, 335 | bitmap: '0xa0000000', 336 | type: 'multi_ed25519_signature' 337 | }, 338 | events: [ 339 | { 340 | key: '0x030000000000000062f8da1b73daf749cab1622f4447be56e2f5e42cfd41f000b68f8f01695d4f54', 341 | sequence_number: '0', 342 | type: '0x1::coin::WithdrawEvent', 343 | data: [Object] 344 | }, 345 | { 346 | key: '0x0200000000000000a24881e004fdbc5550932bb2879129351c21432f21f32d94bf11603bebd9f5c0', 347 | sequence_number: '3', 348 | type: '0x1::coin::DepositEvent', 349 | data: [Object] 350 | } 351 | ], 352 | timestamp: '1662605981259795', 353 | type: 'user_transaction' 354 | } 355 | ``` 356 | -------------------------------------------------------------------------------- /multisig-transaction/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "multisig-transaction", 3 | "version": "1.0.0", 4 | "description": "", 5 | "scripts": { 6 | "test": "echo \"Error: no test specified\" && exit 1" 7 | }, 8 | "author": "", 9 | "license": "ISC", 10 | "dependencies": { 11 | "aptos": "1.3.11", 12 | "commander": "^9.4.0", 13 | "tslib": "^2.4.0" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /multisig-transaction/src/multisign_commit.js: -------------------------------------------------------------------------------- 1 | const { program } = require('commander'); 2 | const { 3 | AptosClient, BCS, HexString, TxnBuilderTypes, TransactionBuilderMultiEd25519, 4 | } = require('aptos'); 5 | const { 6 | Ed25519Signature, RawTransaction, MultiEd25519Signature, MultiEd25519PublicKey 7 | } = TxnBuilderTypes; 8 | 9 | program 10 | .requiredOption('-r, --raw_tx ', "the raw transaction") 11 | .requiredOption('-s, --signatures ', "the signatures of this raw transaction") 12 | .requiredOption('-b, --bitmap ', "the bitmap of this transaction in ascending order. eg. [0 3 31]") 13 | .requiredOption('-u, --url ', "the url to a fullnode on the network") 14 | .requiredOption('-p, --public_key ', "the multi sign public key") 15 | .option('--dry_run', "only dry run not commit", false) 16 | .action(async () => { 17 | const options = program.opts(); 18 | 19 | const signatures = options.signatures.map(function (s) { 20 | return new Ed25519Signature(new HexString(s).toUint8Array()) 21 | }) 22 | 23 | // after aptos v1.3.11 24 | let deserializer = new BCS.Deserializer(new HexString(options.public_key).toUint8Array()); 25 | const multisig_public_key = MultiEd25519PublicKey.deserialize(deserializer); 26 | // after aptos v1.3.11 27 | 28 | // before aptos v1.3.11 29 | // const Ed25519PublicKey = require("aptos").TxnBuilderTypes.Ed25519PublicKey; 30 | // let deserializer = new BCS.Deserializer(new HexString(options.public_key).toUint8Array()); 31 | // const bytes = deserializer.deserializeBytes(); 32 | // const threshold = bytes[bytes.length - 1]; 33 | // const keys = []; 34 | // for (let i = 0; i < bytes.length - 1; i += Ed25519PublicKey.LENGTH) { 35 | // keys.push(new Ed25519PublicKey(bytes.subarray(i, i + Ed25519PublicKey.LENGTH))); 36 | // } 37 | // const multisig_public_key = new MultiEd25519PublicKey(keys, threshold); 38 | // before aptos v1.3.11 39 | 40 | let cap = multisig_public_key.public_keys.length; 41 | if (cap > 32) { 42 | console.log("Invalid multisig public key") 43 | return 44 | } 45 | 46 | const bits = options.bitmap.map(function (i) {return parseInt(i)}); 47 | if (bits.length > 32 48 | || !bits.every(function (i) {return i < 32 && i < cap}) 49 | || !bits.every(function (x,i) {return i === 0 || x >= bits[i-1]}) 50 | ) { 51 | console.log("Invalid bitmap:", options.bitmap); 52 | return 53 | } 54 | 55 | deserializer = new BCS.Deserializer(new HexString(options.raw_tx).toUint8Array()); 56 | const raw_tx = RawTransaction.deserialize(deserializer); 57 | 58 | const expiration = parseInt(raw_tx.expiration_timestamp_secs) 59 | const format_expiration = new Date(expiration * 1000).toISOString().slice(0, 19); 60 | 61 | const entryFunctionPayload = raw_tx.payload.value; 62 | 63 | const coin_address = HexString.fromUint8Array(entryFunctionPayload.ty_args[0].value.address.address).toShortString(); 64 | const coin_module = entryFunctionPayload.ty_args[0].value.module_name.value; 65 | const coin_struct = entryFunctionPayload.ty_args[0].value.name.value; 66 | const coin = coin_address + "::" + coin_module + "::" + coin_struct; 67 | 68 | const receiver = HexString.fromUint8Array(entryFunctionPayload.args[0]).hex(); 69 | const amount = new BCS.Deserializer(entryFunctionPayload.args[1]).deserializeU64(); 70 | 71 | console.log("=========bitmap=========="); 72 | console.log("bitmap:", bits); 73 | console.log("=========bitmap==========\n"); 74 | 75 | console.log("=========multi sign transfer=========="); 76 | console.log("Multi-Address: ", HexString.fromUint8Array(raw_tx.sender.address).hex()); 77 | console.log("Send Coin : ", coin); 78 | console.log("Receiver : ", receiver); 79 | console.log("Amount : ", parseInt(amount)); 80 | console.log("Expiration : ", expiration, "("+format_expiration+")"); 81 | console.log("Sequence : ", parseInt(raw_tx.sequence_number)); 82 | console.log("Chain Id : ", raw_tx.chain_id.value); 83 | console.log("Max gas : ", parseInt(raw_tx.max_gas_amount)); 84 | console.log("=========multi sign transfer==========\n\n"); 85 | 86 | if (options.dry_run) { 87 | return 88 | } 89 | 90 | const client = new AptosClient(options.url); 91 | 92 | const multisig_txn_builder = new TransactionBuilderMultiEd25519((_signingMessage) => { 93 | // Bitmap masks which public key has signed transaction. 94 | const bitmap = MultiEd25519Signature.createBitmap(bits); 95 | return new MultiEd25519Signature(signatures, bitmap); 96 | }, multisig_public_key); 97 | 98 | const multisig_signed_tx = multisig_txn_builder.sign(raw_tx); 99 | const tx_res = await client.submitSignedBCSTransaction(multisig_signed_tx); 100 | 101 | console.log("Multisig Tx hash: ", tx_res.hash); 102 | const [res] = await Promise.all([ 103 | client.waitForTransactionWithResult(tx_res.hash) 104 | ]); 105 | 106 | console.log(res); 107 | }) 108 | .parse(); 109 | -------------------------------------------------------------------------------- /multisig-transaction/src/multisign_create.js: -------------------------------------------------------------------------------- 1 | const { program } = require('commander'); 2 | const HexString = require("aptos").HexString; 3 | const MultiEd25519PublicKey = require("aptos").TxnBuilderTypes.MultiEd25519PublicKey; 4 | const Ed25519PublicKey = require("aptos").TxnBuilderTypes.Ed25519PublicKey; 5 | const AuthenticationKey = require("aptos").TxnBuilderTypes.AuthenticationKey; 6 | const Serializer = require("aptos").BCS.Serializer; 7 | 8 | program 9 | .requiredOption('-p, --pubkey ', 'specify ed25519 pubkeys(MAX=32)') 10 | .requiredOption('-t, --threshold ', 'specify the threshold of multi-sign address') 11 | .action(()=>{ 12 | const options = program.opts(); 13 | console.log("\n----------",options.threshold,"-of-",options.pubkey.length, "Multi-Sign-----"); 14 | 15 | let threshold = parseInt(options.threshold); 16 | if (threshold < 1 || threshold > 32 || threshold > options.pubkey.length) { 17 | console.log("Invalid threshold: ", options.threshold) 18 | return 19 | } 20 | 21 | let pubkeys = [] 22 | let i = 0; 23 | while (i < options.pubkey.length) { 24 | console.log("PubKey", i, ":", options.pubkey[i]); 25 | pubkeys.push( 26 | new Ed25519PublicKey(new HexString(options.pubkey[i]).toUint8Array()) 27 | ) 28 | i = i + 1; 29 | } 30 | 31 | const pubKeyMultiSig = new MultiEd25519PublicKey( 32 | pubkeys, 33 | threshold, 34 | ); 35 | 36 | const authKey = AuthenticationKey.fromMultiEd25519PublicKey(pubKeyMultiSig); 37 | console.log("Multi-Sign AuthKey:", HexString.fromUint8Array(authKey.bytes).hex()); 38 | console.log("Multi-Sign Address:", authKey.derivedAddress().hex()); 39 | 40 | let serializer = new Serializer(); 41 | pubKeyMultiSig.serialize(serializer); 42 | console.log("Multi-Sign Pubkey :", HexString.fromUint8Array(serializer.getBytes()).hex()); 43 | 44 | console.log("----------",options.threshold,"-of-",options.pubkey.length, "Multi-Sign-----"); 45 | }) 46 | .parse(); 47 | -------------------------------------------------------------------------------- /multisig-transaction/src/multisign_register.js: -------------------------------------------------------------------------------- 1 | const { program } = require('commander'); 2 | const { 3 | AptosClient, AptosAccount, HexString, TxnBuilderTypes, TransactionBuilder 4 | } = require('aptos'); 5 | const { 6 | TypeTagStruct, StructTag, TransactionPayloadEntryFunction, 7 | EntryFunction, AccountAddress, RawTransaction 8 | } = TxnBuilderTypes; 9 | 10 | // 1 hour 11 | const MAX_DURATION = 3600; 12 | 13 | program 14 | .requiredOption('-m, --multi_address ', "the sender of the coin") 15 | .requiredOption('--coin ', 'the coin type', "0x1::aptos_coin::AptosCoin") 16 | .requiredOption('--private_key ', 'the privkey for single sign') 17 | .option('--url ', "the url to a fullnode on the network") 18 | .option('--chain_id ', 'the chain id, use query if url set') 19 | .option('--sequence ', 'the sequence number, use query if url set') 20 | .option('--max_gas ', 'the max gas for this transaction', "1000") 21 | .option('--expiration ', 'transaction is discarded if it is not executed before expiration timestamp') 22 | .action(async () => { 23 | const options = program.opts(); 24 | const max_gas = parseInt(options.max_gas) < 4000000n ? parseInt(options.max_gas): 4000000n; 25 | const private_key_bytes = new HexString(options.private_key).toUint8Array(); 26 | const sign_account = new AptosAccount(private_key_bytes); 27 | let chain_id = 0; 28 | let sequence = 0; 29 | if (options.url === undefined) { 30 | if (options.chain_id === undefined || options.sequence === undefined) { 31 | console.log("chain_id or sequence is not set") 32 | return 33 | } 34 | 35 | chain_id = parseInt(options.chain_id); 36 | sequence = options.sequence; 37 | } else { 38 | console.log("query chain_id and sequence from the fullnode:") 39 | console.log("fullnode url: ", options.url); 40 | 41 | const client = new AptosClient(options.url); 42 | const [{ sequence_number }, _chain_id] = await Promise.all([ 43 | client.getAccount(options.multi_address), 44 | client.getChainId(), 45 | ]); 46 | sequence = sequence_number; 47 | chain_id = _chain_id; 48 | } 49 | 50 | const expiration = options.expiration === undefined ? 51 | Math.floor(Date.now() / 1000) + MAX_DURATION : 52 | parseInt(options.expiration); 53 | const format_expiration = new Date(expiration * 1000).toISOString().slice(0, 19); 54 | 55 | console.log("\n-------", sign_account.address().hex(), "build-------\n"); 56 | console.log("=========multi sign register=========="); 57 | console.log("Multi-Address: ", options.multi_address); 58 | console.log("Register Coin: ", options.coin); 59 | console.log("Expiration : ", expiration, "("+format_expiration+")"); 60 | console.log("Sequence : ", sequence) 61 | console.log("Chain Id : ", chain_id) 62 | console.log("Max gas : ", max_gas); 63 | console.log("=========multi sign register=========="); 64 | 65 | const coin = new TypeTagStruct(StructTag.fromString(options.coin)); 66 | 67 | const entryFunctionPayload = new TransactionPayloadEntryFunction( 68 | EntryFunction.natural( 69 | // Fully qualified module name, `AccountAddress::ModuleName` 70 | "0x1::managed_coin", 71 | // Module function 72 | "register", 73 | // The coin type to register 74 | [coin], 75 | [], 76 | ), 77 | ); 78 | 79 | const mutisig_address = AccountAddress.fromHex(options.multi_address); 80 | const rawTxn = new RawTransaction( 81 | // Transaction sender account address 82 | mutisig_address, 83 | BigInt(sequence), 84 | entryFunctionPayload, 85 | // Max gas unit to spend 86 | max_gas, 87 | // Gas price per unit 88 | 1n, 89 | // Expiration timestamp. Transaction is discarded if it is not executed within 1 hour from now. 90 | BigInt(expiration), 91 | new TxnBuilderTypes.ChainId(chain_id), 92 | ); 93 | 94 | const sign_message = TransactionBuilder.getSigningMessage(rawTxn); 95 | 96 | console.log("\nRaw Transaction: ", HexString.fromUint8Array(sign_message).hex()) 97 | 98 | const single_signature = sign_account.signBuffer(sign_message).hex() 99 | 100 | console.log("\nsingle_signature: ", single_signature) 101 | }) 102 | .parse(); 103 | -------------------------------------------------------------------------------- /multisig-transaction/src/multisign_transfer.js: -------------------------------------------------------------------------------- 1 | const { program } = require('commander'); 2 | const { 3 | AptosClient, AptosAccount, BCS, HexString, TxnBuilderTypes, 4 | TransactionBuilder 5 | } = require('aptos'); 6 | const { 7 | TypeTagStruct, StructTag, TransactionPayloadEntryFunction, 8 | EntryFunction, AccountAddress, RawTransaction 9 | } = TxnBuilderTypes; 10 | 11 | // 1 hour 12 | const MAX_DURATION = 3600; 13 | 14 | program 15 | .requiredOption('-m, --multi_address ', "the sender of the coin") 16 | .requiredOption('-r, --receiver ', "the receiver of the coin") 17 | .requiredOption('-a, --amount ', "the amount of the coin") 18 | .requiredOption('--coin ', 'the coin type', "0x1::aptos_coin::AptosCoin") 19 | .requiredOption('--private_key ', 'the privkey for single sign') 20 | .option('--url ', "the url to a fullnode on the network") 21 | .option('--chain_id ', 'the chain id, use query if url set') 22 | .option('--sequence ', 'the sequence number, use query if url set') 23 | .option('--max_gas ', 'the max gas for this transaction', "1000") 24 | .option('--expiration ', 'transaction is discarded if it is not executed before expiration timestamp') 25 | .action(async () => { 26 | const options = program.opts(); 27 | const max_gas = parseInt(options.max_gas) < 4000000n ? parseInt(options.max_gas): 4000000n; 28 | const private_key_bytes = new HexString(options.private_key).toUint8Array(); 29 | const sign_account = new AptosAccount(private_key_bytes); 30 | let chain_id = 0; 31 | let sequence = 0; 32 | if (options.url === undefined) { 33 | if (options.chain_id === undefined || options.sequence === undefined) { 34 | console.log("chain_id or sequence is not set") 35 | return 36 | } 37 | 38 | chain_id = parseInt(options.chain_id); 39 | sequence = options.sequence; 40 | } else { 41 | console.log("query chain_id and sequence from the fullnode:") 42 | console.log("fullnode url: ", options.url); 43 | 44 | const client = new AptosClient(options.url); 45 | const [{ sequence_number }, _chain_id] = await Promise.all([ 46 | client.getAccount(options.multi_address), 47 | client.getChainId(), 48 | ]); 49 | sequence = sequence_number; 50 | chain_id = _chain_id; 51 | } 52 | 53 | const expiration = options.expiration === undefined ? 54 | Math.floor(Date.now() / 1000) + MAX_DURATION : 55 | parseInt(options.expiration); 56 | const format_expiration = new Date(expiration * 1000).toISOString().slice(0, 19); 57 | 58 | console.log("\n-------", sign_account.address().hex(), "build-------\n"); 59 | console.log("=========multi sign transfer=========="); 60 | console.log("Multi-Address: ", options.multi_address); 61 | console.log("Send Coin : ", options.coin); 62 | console.log("Receiver : ", options.receiver); 63 | console.log("Amount : ", options.amount); 64 | console.log("Expiration : ", expiration, "("+format_expiration+")"); 65 | console.log("Sequence : ", sequence) 66 | console.log("Chain Id : ", chain_id) 67 | console.log("Max gas : ", max_gas); 68 | console.log("=========multi sign transfer=========="); 69 | 70 | const coin = new TypeTagStruct(StructTag.fromString(options.coin)); 71 | const receiver = AccountAddress.fromHex(options.receiver); 72 | const amount = parseInt(BigInt.asUintN(64, BigInt(options.amount))); 73 | 74 | const entryFunctionPayload = new TransactionPayloadEntryFunction( 75 | EntryFunction.natural( 76 | // Fully qualified module name, `AccountAddress::ModuleName` 77 | "0x1::coin", 78 | // Module function 79 | "transfer", 80 | // The coin type to transfer 81 | [coin], 82 | // Arguments for function `transfer`: receiver account address and amount to transfer 83 | [ 84 | BCS.bcsToBytes(receiver), 85 | BCS.bcsSerializeUint64(amount) 86 | ], 87 | ), 88 | ); 89 | 90 | const mutisig_address = AccountAddress.fromHex(options.multi_address); 91 | const rawTxn = new RawTransaction( 92 | // Transaction sender account address 93 | mutisig_address, 94 | BigInt(sequence), 95 | entryFunctionPayload, 96 | // Max gas unit to spend 97 | max_gas, 98 | // Gas price per unit 99 | 1n, 100 | // Expiration timestamp. Transaction is discarded if it is not executed within 1 hour from now. 101 | BigInt(expiration), 102 | new TxnBuilderTypes.ChainId(chain_id), 103 | ); 104 | 105 | let serializer = new BCS.Serializer(); 106 | rawTxn.serialize(serializer); 107 | 108 | console.log("\nRaw Transaction(BCS): ", HexString.fromUint8Array(serializer.getBytes()).hex()) 109 | 110 | const sign_message = TransactionBuilder.getSigningMessage(rawTxn); 111 | const single_signature = sign_account.signBuffer(sign_message).hex() 112 | 113 | console.log("\nsingle_signature: ", single_signature) 114 | }) 115 | .parse(); 116 | -------------------------------------------------------------------------------- /multisig-transaction/yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@noble/hashes@~1.1.1": 6 | version "1.1.2" 7 | resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.1.2.tgz#e9e035b9b166ca0af657a7848eb2718f0f22f183" 8 | integrity sha512-KYRCASVTv6aeUi1tsF8/vpyR7zpfs3FUzy2Jqm+MU+LmUKhQ0y2FpfwqkCcxSg2ua4GALJd8k2R76WxwZGbQpA== 9 | 10 | "@scure/base@~1.1.0": 11 | version "1.1.1" 12 | resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.1.1.tgz#ebb651ee52ff84f420097055f4bf46cfba403938" 13 | integrity sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA== 14 | 15 | "@scure/bip39@^1.1.0": 16 | version "1.1.0" 17 | resolved "https://registry.yarnpkg.com/@scure/bip39/-/bip39-1.1.0.tgz#92f11d095bae025f166bef3defcc5bf4945d419a" 18 | integrity sha512-pwrPOS16VeTKg98dYXQyIjJEcWfz7/1YJIwxUEPFfQPtc86Ym/1sVgQ2RLoD43AazMk2l/unK4ITySSpW2+82w== 19 | dependencies: 20 | "@noble/hashes" "~1.1.1" 21 | "@scure/base" "~1.1.0" 22 | 23 | aptos@1.3.11: 24 | version "1.3.11" 25 | resolved "https://registry.yarnpkg.com/aptos/-/aptos-1.3.11.tgz#6063113c734e18909b0d7f7233a99cc574153fd4" 26 | integrity sha512-IaiXvKGFrL7/dg931KjOU6ny59lCV724NyNNJF/L4zigTsV0+EIGGAyaJBOvWedPr43qrY6CKiEdkDjXsOQJSA== 27 | dependencies: 28 | "@scure/bip39" "^1.1.0" 29 | axios "^0.27.2" 30 | ed25519-hd-key "^1.2.0" 31 | js-sha3 "^0.8.0" 32 | tweetnacl "^1.0.3" 33 | typescript-memoize "^1.1.0" 34 | 35 | asynckit@^0.4.0: 36 | version "0.4.0" 37 | resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" 38 | integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== 39 | 40 | axios@^0.27.2: 41 | version "0.27.2" 42 | resolved "https://registry.yarnpkg.com/axios/-/axios-0.27.2.tgz#207658cc8621606e586c85db4b41a750e756d972" 43 | integrity sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ== 44 | dependencies: 45 | follow-redirects "^1.14.9" 46 | form-data "^4.0.0" 47 | 48 | cipher-base@^1.0.1, cipher-base@^1.0.3: 49 | version "1.0.4" 50 | resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" 51 | integrity sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q== 52 | dependencies: 53 | inherits "^2.0.1" 54 | safe-buffer "^5.0.1" 55 | 56 | combined-stream@^1.0.8: 57 | version "1.0.8" 58 | resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" 59 | integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== 60 | dependencies: 61 | delayed-stream "~1.0.0" 62 | 63 | commander@^9.4.0: 64 | version "9.4.0" 65 | resolved "https://registry.yarnpkg.com/commander/-/commander-9.4.0.tgz#bc4a40918fefe52e22450c111ecd6b7acce6f11c" 66 | integrity sha512-sRPT+umqkz90UA8M1yqYfnHlZA7fF6nSphDtxeywPZ49ysjxDQybzk13CL+mXekDRG92skbcqCLVovuCusNmFw== 67 | 68 | create-hash@^1.1.0: 69 | version "1.2.0" 70 | resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" 71 | integrity sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg== 72 | dependencies: 73 | cipher-base "^1.0.1" 74 | inherits "^2.0.1" 75 | md5.js "^1.3.4" 76 | ripemd160 "^2.0.1" 77 | sha.js "^2.4.0" 78 | 79 | create-hmac@1.1.7: 80 | version "1.1.7" 81 | resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" 82 | integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg== 83 | dependencies: 84 | cipher-base "^1.0.3" 85 | create-hash "^1.1.0" 86 | inherits "^2.0.1" 87 | ripemd160 "^2.0.0" 88 | safe-buffer "^5.0.1" 89 | sha.js "^2.4.8" 90 | 91 | delayed-stream@~1.0.0: 92 | version "1.0.0" 93 | resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" 94 | integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== 95 | 96 | ed25519-hd-key@^1.2.0: 97 | version "1.3.0" 98 | resolved "https://registry.yarnpkg.com/ed25519-hd-key/-/ed25519-hd-key-1.3.0.tgz#e0bd2be4c07e15c753d5ed3aca30744e321b7c78" 99 | integrity sha512-IWwAyiiuJQhgu3L8NaHb68eJxTu2pgCwxIBdgpLJdKpYZM46+AXePSVTr7fkNKaUOfOL4IrjEUaQvyVRIDP7fg== 100 | dependencies: 101 | create-hmac "1.1.7" 102 | tweetnacl "1.0.3" 103 | 104 | follow-redirects@^1.14.9: 105 | version "1.15.1" 106 | resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.1.tgz#0ca6a452306c9b276e4d3127483e29575e207ad5" 107 | integrity sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA== 108 | 109 | form-data@^4.0.0: 110 | version "4.0.0" 111 | resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" 112 | integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww== 113 | dependencies: 114 | asynckit "^0.4.0" 115 | combined-stream "^1.0.8" 116 | mime-types "^2.1.12" 117 | 118 | hash-base@^3.0.0: 119 | version "3.1.0" 120 | resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.1.0.tgz#55c381d9e06e1d2997a883b4a3fddfe7f0d3af33" 121 | integrity sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA== 122 | dependencies: 123 | inherits "^2.0.4" 124 | readable-stream "^3.6.0" 125 | safe-buffer "^5.2.0" 126 | 127 | inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4: 128 | version "2.0.4" 129 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" 130 | integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== 131 | 132 | js-sha3@^0.8.0: 133 | version "0.8.0" 134 | resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.8.0.tgz#b9b7a5da73afad7dedd0f8c463954cbde6818840" 135 | integrity sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q== 136 | 137 | md5.js@^1.3.4: 138 | version "1.3.5" 139 | resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" 140 | integrity sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg== 141 | dependencies: 142 | hash-base "^3.0.0" 143 | inherits "^2.0.1" 144 | safe-buffer "^5.1.2" 145 | 146 | mime-db@1.52.0: 147 | version "1.52.0" 148 | resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" 149 | integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== 150 | 151 | mime-types@^2.1.12: 152 | version "2.1.35" 153 | resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" 154 | integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== 155 | dependencies: 156 | mime-db "1.52.0" 157 | 158 | readable-stream@^3.6.0: 159 | version "3.6.0" 160 | resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" 161 | integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== 162 | dependencies: 163 | inherits "^2.0.3" 164 | string_decoder "^1.1.1" 165 | util-deprecate "^1.0.1" 166 | 167 | ripemd160@^2.0.0, ripemd160@^2.0.1: 168 | version "2.0.2" 169 | resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" 170 | integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA== 171 | dependencies: 172 | hash-base "^3.0.0" 173 | inherits "^2.0.1" 174 | 175 | safe-buffer@^5.0.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@~5.2.0: 176 | version "5.2.1" 177 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" 178 | integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== 179 | 180 | sha.js@^2.4.0, sha.js@^2.4.8: 181 | version "2.4.11" 182 | resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" 183 | integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ== 184 | dependencies: 185 | inherits "^2.0.1" 186 | safe-buffer "^5.0.1" 187 | 188 | string_decoder@^1.1.1: 189 | version "1.3.0" 190 | resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" 191 | integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== 192 | dependencies: 193 | safe-buffer "~5.2.0" 194 | 195 | tslib@^2.4.0: 196 | version "2.4.0" 197 | resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3" 198 | integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ== 199 | 200 | tweetnacl@1.0.3, tweetnacl@^1.0.3: 201 | version "1.0.3" 202 | resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-1.0.3.tgz#ac0af71680458d8a6378d0d0d050ab1407d35596" 203 | integrity sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw== 204 | 205 | typescript-memoize@^1.1.0: 206 | version "1.1.0" 207 | resolved "https://registry.yarnpkg.com/typescript-memoize/-/typescript-memoize-1.1.0.tgz#4a8f512d06fc995167c703a3592219901db8bc79" 208 | integrity sha512-LQPKVXK8QrBBkL/zclE6YgSWn0I8ew5m0Lf+XL00IwMhlotqRLlzHV+BRrljVQIc+NohUAuQP7mg4HQwrx5Xbg== 209 | 210 | util-deprecate@^1.0.1: 211 | version "1.0.2" 212 | resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" 213 | integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== 214 | -------------------------------------------------------------------------------- /mycoin/Move.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "mycoin" 3 | version = "0.1.0" 4 | license = "Apache-2.0" 5 | 6 | [dependencies] 7 | #AptosFramework = { git = "https://github.com/aptos-labs/aptos-core.git", subdir = "aptos-move/framework/aptos-framework/", rev = "2c1e2dd5be5c71dd8069c7a6382d9f911a1cd5d0" } 8 | #AptosStdlib = { git = "https://github.com/aptos-labs/aptos-core.git", subdir = "aptos-move/framework/aptos-stdlib", rev = "2c1e2dd5be5c71dd8069c7a6382d9f911a1cd5d0" } 9 | AptosFramework = { local = "../../aptos-core/aptos-move/framework/aptos-framework" } 10 | AptosStdlib = { local = "../../aptos-core/aptos-move/framework/aptos-stdlib" } 11 | 12 | [addresses] 13 | mycoin = "_" 14 | -------------------------------------------------------------------------------- /mycoin/README.md: -------------------------------------------------------------------------------- 1 | # How to issue your coins on aptos 2 | 3 | ## precondition for this example 4 | - [aptos-cli](https://github.com/aptos-labs/aptos-core/releases) 5 | - two accounts: 6 | - `owner`(default): publish coins contract, mint and burn the coins 7 | ```txt 8 | private_key: "0x1d5c699949317f8b41f31ddff29332943b1c31dd916e1b6747f408852e25f16f" 9 | public_key: "0x027b9579c66cbfae60651b7c5f41fcb65eff5e229f29503f17f1eb0780981b89" 10 | account: d02617efb7147fc1b313d6a6feadef2fc5b21e38268cea50f51ec2222ae64a2f 11 | ``` 12 | - `receiver`: receive the coins 13 | ```txt 14 | private_key: "0xc43f88efcf5b14dc9ba00f3d73e8a455df260e730133fcd81386df1d463d0332" 15 | public_key: "0x9a6c8012d9ac973e976cb85d15f611da4f32f95cf0f55e9bf7e03c2fc347bcd1" 16 | account: 2e39b3b448114792d41ea4ee26f536595a001f734f94b5bd56ae3de6c3096cb0 17 | ``` 18 | 19 | ### publish by owner 20 | ```bash 21 | aptos move publish \ 22 | --named-addresses mycoin=0xd02617efb7147fc1b313d6a6feadef2fc5b21e38268cea50f51ec2222ae64a2f 23 | ``` 24 | 25 | ### initialize by owner 26 | ```bash 27 | aptos move run \ 28 | --function-id 0x1::managed_coin::initialize \ 29 | --args string:"Test Coin" string:"Test" u8:8 bool:true \ 30 | --type-args 0xd02617efb7147fc1b313d6a6feadef2fc5b21e38268cea50f51ec2222ae64a2f::Coins::TestCoin 31 | ``` 32 | 33 | ### register for owner 34 | ```bash 35 | aptos move run --function-id 0x1::managed_coin::register \ 36 | --type-args 0xd02617efb7147fc1b313d6a6feadef2fc5b21e38268cea50f51ec2222ae64a2f::Coins::TestCoin 37 | ``` 38 | 39 | ### mint to owner 40 | ```bash 41 | aptos move run --function-id 0x1::managed_coin::mint \ 42 | --args address:0xd02617efb7147fc1b313d6a6feadef2fc5b21e38268cea50f51ec2222ae64a2f u64:10000 \ 43 | --type-args 0xd02617efb7147fc1b313d6a6feadef2fc5b21e38268cea50f51ec2222ae64a2f::Coins::TestCoin 44 | ``` 45 | 46 | ### only burn from owner 47 | ```bash 48 | aptos move run --function-id 0x1::managed_coin::burn \ 49 | --args u64:1000 \ 50 | --type-args 0xd02617efb7147fc1b313d6a6feadef2fc5b21e38268cea50f51ec2222ae64a2f::Coins::TestCoin 51 | ``` 52 | 53 | ### register for receiver 54 | ```bash 55 | aptos move run --function-id 0x1::managed_coin::register \ 56 | --type-args 0xd02617efb7147fc1b313d6a6feadef2fc5b21e38268cea50f51ec2222ae64a2f::Coins::TestCoin \ 57 | --private-key 0xc43f88efcf5b14dc9ba00f3d73e8a455df260e730133fcd81386df1d463d0332 58 | ``` 59 | 60 | ### mint to receiver by owner 61 | ```bash 62 | aptos move run --function-id 0x1::managed_coin::mint \ 63 | --args address:0x2e39b3b448114792d41ea4ee26f536595a001f734f94b5bd56ae3de6c3096cb0 u64:10000 \ 64 | --type-args 0xd02617efb7147fc1b313d6a6feadef2fc5b21e38268cea50f51ec2222ae64a2f::Coins::TestCoin 65 | ``` 66 | 67 | ### transfer from receiver to owner 68 | ```bash 69 | aptos move run --function-id 0x1::coin::transfer \ 70 | --args address:0xd02617efb7147fc1b313d6a6feadef2fc5b21e38268cea50f51ec2222ae64a2f u64:111 \ 71 | --type-args 0xd02617efb7147fc1b313d6a6feadef2fc5b21e38268cea50f51ec2222ae64a2f::Coins::TestCoin \ 72 | --private-key 0xc43f88efcf5b14dc9ba00f3d73e8a455df260e730133fcd81386df1d463d0332 73 | ``` 74 | 75 | ### query the coin 76 | ```bash 77 | # query owner 78 | aptos account list --account 0xd02617efb7147fc1b313d6a6feadef2fc5b21e38268cea50f51ec2222ae64a2f 79 | # quert receiver 80 | aptos account list --account 0x2e39b3b448114792d41ea4ee26f536595a001f734f94b5bd56ae3de6c3096cb0 81 | ``` 82 | 83 | ### Ditto for XBTC and XETH 84 | ```bash 85 | aptos move run \ 86 | --function-id 0x1::managed_coin::initialize \ 87 | --args string:"XBTC" string:"XBTC" u8:8 bool:true \ 88 | --type-args 0xd02617efb7147fc1b313d6a6feadef2fc5b21e38268cea50f51ec2222ae64a2f::Coins::XBTC 89 | 90 | aptos move run \ 91 | --function-id 0x1::managed_coin::initialize \ 92 | --args string:"XETH" string:"XETH" u8:18 bool:true \ 93 | --type-args 0xd02617efb7147fc1b313d6a6feadef2fc5b21e38268cea50f51ec2222ae64a2f::Coins::XETH 94 | ``` 95 | -------------------------------------------------------------------------------- /mycoin/sources/coins.move: -------------------------------------------------------------------------------- 1 | module mycoin::Coins { 2 | struct TestCoin {} 3 | 4 | struct XBTC {} 5 | 6 | struct XETH {} 7 | } 8 | -------------------------------------------------------------------------------- /sui-scripts/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "scripts", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "@mysten/sui.js": "^0.21.0", 13 | "ts-retry-promise": "^0.7.0" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /sui-scripts/src/devInspectMoveCall.js: -------------------------------------------------------------------------------- 1 | const { JsonRpcProvider } = require("@mysten/sui.js"); 2 | 3 | (async ()=> { 4 | const DEVNET_URL = "https://fullnode.devnet.sui.io:443"; 5 | 6 | const address = "0xf15b467c66c983310d3966e84bdf0c399963842c"; 7 | 8 | const provider = new JsonRpcProvider(DEVNET_URL); 9 | 10 | const coins = await provider.getGasObjectsOwnedByAddress(address); 11 | console.log("coins[0]: ", coins[0].objectId); 12 | console.log("coins[1]: ", coins[1].objectId); 13 | 14 | const result = await provider.devInspectMoveCall( 15 | address, 16 | { 17 | packageObjectId: '0x2', 18 | module: 'coin', 19 | function: 'value', 20 | typeArguments: ["0x2::sui::SUI"], 21 | arguments: [coins[1].objectId], 22 | } 23 | ); 24 | 25 | let buffer = Buffer.from(result.results.Ok[0][1].returnValues[0][0]); 26 | let balance = buffer.readBigUInt64LE(0); 27 | console.log("coins[1] balance: ",balance.toString()); 28 | })() -------------------------------------------------------------------------------- /sui-scripts/src/devInspectTransaction.js: -------------------------------------------------------------------------------- 1 | const { 2 | JsonRpcProvider, Ed25519Keypair, LocalTxnDataSerializer, RawSigner 3 | } = require("@mysten/sui.js"); 4 | const { retry } = require("ts-retry-promise"); 5 | 6 | (async ()=> { 7 | const DEVNET_URL = "https://fullnode.devnet.sui.io:443"; 8 | const DEVNET_FAUCET_URL = "https://faucet.devnet.sui.io/gas"; 9 | 10 | const keypair = Ed25519Keypair.deriveKeypair(process.env.TEST_MNEMONIC); 11 | const address = keypair.getPublicKey().toSuiAddress(); 12 | console.log("address: ", address); 13 | 14 | const provider = new JsonRpcProvider( 15 | DEVNET_URL, 16 | { 17 | skipDataValidation: false, 18 | faucetURL: DEVNET_FAUCET_URL, 19 | } 20 | ); 21 | 22 | // try { 23 | // await retry(() => provider.requestSuiFromFaucet(address), { 24 | // backoff: 'EXPONENTIAL', 25 | // // overall timeout in 6 seconds 26 | // timeout: 1000 * 6, 27 | // logger: (msg) => console.warn('Retrying requesting from faucet: ' + msg), 28 | // }); 29 | // } catch (e) { 30 | // // nothing 31 | // } 32 | 33 | const signer = new RawSigner( 34 | keypair, 35 | provider, 36 | new LocalTxnDataSerializer(provider) 37 | ); 38 | const coins = await provider.getGasObjectsOwnedByAddress(address); 39 | console.log("coins[0]: ", coins[0].objectId); 40 | console.log("coins[1]: ", coins[1].objectId); 41 | 42 | const result = await signer.devInspectTransaction( 43 | { 44 | kind: 'moveCall', 45 | data: { 46 | packageObjectId: '0x2', 47 | module: 'coin', 48 | function: 'value', 49 | typeArguments: ["0x2::sui::SUI"], 50 | arguments: [coins[1].objectId], 51 | gasBudget: 10000, 52 | gasPayment: coins[0].objectId 53 | }, 54 | } 55 | ); 56 | 57 | let buffer = Buffer.from(result.results.Ok[0][1].returnValues[0][0]); 58 | let balance = buffer.readBigUInt64LE(0); 59 | console.log("coins[1] balance: ",balance.toString()); 60 | })() -------------------------------------------------------------------------------- /sui-scripts/src/dryRunTransaction.js: -------------------------------------------------------------------------------- 1 | const { 2 | JsonRpcProvider, Ed25519Keypair, LocalTxnDataSerializer, RawSigner, ObjectId 3 | } = require("@mysten/sui.js"); 4 | const { retry } = require("ts-retry-promise"); 5 | 6 | (async ()=> { 7 | const DEVNET_URL = "https://fullnode.devnet.sui.io:443"; 8 | const DEVNET_FAUCET_URL = "https://faucet.devnet.sui.io/gas"; 9 | 10 | const keypair = Ed25519Keypair.deriveKeypair(process.env.TEST_MNEMONIC); 11 | const address = keypair.getPublicKey().toSuiAddress(); 12 | console.log("address: ", address); 13 | 14 | const provider = new JsonRpcProvider( 15 | DEVNET_URL, 16 | { 17 | skipDataValidation: false, 18 | faucetURL: DEVNET_FAUCET_URL, 19 | } 20 | ); 21 | 22 | // try { 23 | // await retry(() => provider.requestSuiFromFaucet(address), { 24 | // backoff: 'EXPONENTIAL', 25 | // // overall timeout in 6 seconds 26 | // timeout: 1000 * 6, 27 | // logger: (msg) => console.warn('Retrying requesting from faucet: ' + msg), 28 | // }); 29 | // } catch (e) { 30 | // // nothing 31 | // } 32 | 33 | const signer = new RawSigner( 34 | keypair, 35 | provider, 36 | new LocalTxnDataSerializer(provider) 37 | ); 38 | const coins = await provider.getGasObjectsOwnedByAddress(address); 39 | console.log("coins[0]: ", coins[0].objectId); 40 | 41 | const result = await signer.dryRunTransaction( 42 | { 43 | kind: 'moveCall', 44 | data: { 45 | packageObjectId: '0x2', 46 | module: 'devnet_nft', 47 | function: 'mint', 48 | typeArguments: [], 49 | arguments: [ 50 | 'Example NFT', 51 | 'An NFT created by the wallet Command Line Tool', 52 | 'ipfs://bafkreibngqhl3gaa7daob4i2vccziay2jjlp435cf66vhono7nrvww53ty', 53 | ], 54 | gasBudget: 10000, 55 | gasPayment: coins[0].objectId 56 | }, 57 | } 58 | ); 59 | 60 | console.log(result); 61 | })() -------------------------------------------------------------------------------- /sui-scripts/src/executeTransaction.js: -------------------------------------------------------------------------------- 1 | const { 2 | JsonRpcProvider, Ed25519Keypair, LocalTxnDataSerializer, RawSigner, ObjectId 3 | } = require("@mysten/sui.js"); 4 | const { retry } = require("ts-retry-promise"); 5 | 6 | (async ()=> { 7 | const DEVNET_URL = "https://fullnode.devnet.sui.io:443"; 8 | const DEVNET_FAUCET_URL = "https://faucet.devnet.sui.io/gas"; 9 | 10 | const keypair = Ed25519Keypair.deriveKeypair(process.env.TEST_MNEMONIC); 11 | const address = keypair.getPublicKey().toSuiAddress(); 12 | console.log("address: ", address); 13 | 14 | const provider = new JsonRpcProvider( 15 | DEVNET_URL, 16 | { 17 | skipDataValidation: false, 18 | faucetURL: DEVNET_FAUCET_URL, 19 | } 20 | ); 21 | 22 | try { 23 | await retry(() => provider.requestSuiFromFaucet(address), { 24 | backoff: 'EXPONENTIAL', 25 | // overall timeout in 6 seconds 26 | timeout: 1000 * 6, 27 | logger: (msg) => console.warn('Retrying requesting from faucet: ' + msg), 28 | }); 29 | } catch (e) { 30 | // nothing 31 | } 32 | 33 | const signer = new RawSigner( 34 | keypair, 35 | provider, 36 | new LocalTxnDataSerializer(provider) 37 | ); 38 | const coins = await provider.getGasObjectsOwnedByAddress(address); 39 | console.log("coins[0]: ", coins[0].objectId); 40 | 41 | const result = await signer.signAndExecuteTransaction( 42 | { 43 | kind: 'moveCall', 44 | data: { 45 | packageObjectId: '0x2', 46 | module: 'devnet_nft', 47 | function: 'mint', 48 | typeArguments: [], 49 | arguments: [ 50 | 'Example NFT', 51 | 'An NFT created by the wallet Command Line Tool', 52 | 'ipfs://bafkreibngqhl3gaa7daob4i2vccziay2jjlp435cf66vhono7nrvww53ty', 53 | ], 54 | gasBudget: 10000, 55 | gasPayment: coins[0].objectId 56 | }, 57 | } 58 | ); 59 | 60 | console.log(result); 61 | })() -------------------------------------------------------------------------------- /sui-scripts/src/get_objects.js: -------------------------------------------------------------------------------- 1 | const {JsonRpcProvider} = require("@mysten/sui.js"); 2 | 3 | (async ()=> { 4 | const TESTNET_URL = "https://fullnode.testnet.sui.io:443"; 5 | 6 | let client = new JsonRpcProvider(TESTNET_URL); 7 | let bagId = "0x9f7e2cd16df60de1ba4425053a87e284706256db"; 8 | let keys = await client.getObjectsOwnedByObject(bagId); 9 | 10 | console.log(keys); 11 | 12 | let value = await client.getObject(keys[0].objectId); 13 | 14 | console.log(value); 15 | })() 16 | -------------------------------------------------------------------------------- /sui-scripts/yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@babel/runtime@^7.17.2": 6 | version "7.20.1" 7 | resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.20.1.tgz#1148bb33ab252b165a06698fde7576092a78b4a9" 8 | integrity sha512-mrzLkl6U9YLF8qpqI7TB82PESyEGjm/0Ly91jG575eVxMMlb8fYfOXFZIJ8XfLrJZQbm7dlKry2bJmXBUEkdFg== 9 | dependencies: 10 | regenerator-runtime "^0.13.10" 11 | 12 | "@mysten/bcs@0.5.0": 13 | version "0.5.0" 14 | resolved "https://registry.yarnpkg.com/@mysten/bcs/-/bcs-0.5.0.tgz#d2570971e3d9121b83091ced38db13e907ab4198" 15 | integrity sha512-FjGnXZfR4dY01Q1l3xjgaU+ruIlVomXZk8vzgsQXPFOv7O4pNiOOpJyMEMUnWcyUiktk4R9MxoJJrygOtdxaUw== 16 | 17 | "@mysten/sui.js@^0.21.0": 18 | version "0.21.0" 19 | resolved "https://registry.yarnpkg.com/@mysten/sui.js/-/sui.js-0.21.0.tgz#49a532cfb201d2f4ac047462292f722aa982ac5f" 20 | integrity sha512-sIHDcNlC7IQ3za5tecBe5TRDqqwU8BZLvA2RkcQuIDsJZRDg8aJxv7n2JZwH4tWkx/aT4Bs378kwKxZkwTwUuQ== 21 | dependencies: 22 | "@mysten/bcs" "0.5.0" 23 | "@noble/hashes" "^1.1.2" 24 | "@noble/secp256k1" "^1.6.3" 25 | "@scure/bip32" "^1.1.0" 26 | "@scure/bip39" "^1.1.0" 27 | "@suchipi/femver" "^1.0.0" 28 | bs58 "^5.0.0" 29 | cross-fetch "^3.1.5" 30 | jayson "^3.6.6" 31 | js-sha3 "^0.8.0" 32 | rpc-websockets "^7.5.0" 33 | superstruct "^1.0.3" 34 | tweetnacl "^1.0.3" 35 | 36 | "@noble/hashes@^1.1.2", "@noble/hashes@~1.1.1", "@noble/hashes@~1.1.3": 37 | version "1.1.3" 38 | resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.1.3.tgz#360afc77610e0a61f3417e497dcf36862e4f8111" 39 | integrity sha512-CE0FCR57H2acVI5UOzIGSSIYxZ6v/HOhDR0Ro9VLyhnzLwx0o8W1mmgaqlEUx4049qJDlIBRztv5k+MM8vbO3A== 40 | 41 | "@noble/secp256k1@^1.6.3", "@noble/secp256k1@~1.7.0": 42 | version "1.7.0" 43 | resolved "https://registry.yarnpkg.com/@noble/secp256k1/-/secp256k1-1.7.0.tgz#d15357f7c227e751d90aa06b05a0e5cf993ba8c1" 44 | integrity sha512-kbacwGSsH/CTout0ZnZWxnW1B+jH/7r/WAAKLBtrRJ/+CUH7lgmQzl3GTrQua3SGKWNSDsS6lmjnDpIJ5Dxyaw== 45 | 46 | "@scure/base@~1.1.0": 47 | version "1.1.1" 48 | resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.1.1.tgz#ebb651ee52ff84f420097055f4bf46cfba403938" 49 | integrity sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA== 50 | 51 | "@scure/bip32@^1.1.0": 52 | version "1.1.1" 53 | resolved "https://registry.yarnpkg.com/@scure/bip32/-/bip32-1.1.1.tgz#f62e4a2f13cc3e5e720ad81b7582b8631ae6835a" 54 | integrity sha512-UmI+liY7np2XakaW+6lMB6HZnpczWk1yXZTxvg8TM8MdOcKHCGL1YkraGj8eAjPfMwFNiAyek2hXmS/XFbab8g== 55 | dependencies: 56 | "@noble/hashes" "~1.1.3" 57 | "@noble/secp256k1" "~1.7.0" 58 | "@scure/base" "~1.1.0" 59 | 60 | "@scure/bip39@^1.1.0": 61 | version "1.1.0" 62 | resolved "https://registry.yarnpkg.com/@scure/bip39/-/bip39-1.1.0.tgz#92f11d095bae025f166bef3defcc5bf4945d419a" 63 | integrity sha512-pwrPOS16VeTKg98dYXQyIjJEcWfz7/1YJIwxUEPFfQPtc86Ym/1sVgQ2RLoD43AazMk2l/unK4ITySSpW2+82w== 64 | dependencies: 65 | "@noble/hashes" "~1.1.1" 66 | "@scure/base" "~1.1.0" 67 | 68 | "@suchipi/femver@^1.0.0": 69 | version "1.0.0" 70 | resolved "https://registry.yarnpkg.com/@suchipi/femver/-/femver-1.0.0.tgz#4909dcc069695e07bd23a64c4bfe411d11d9692f" 71 | integrity sha512-bprE8+K5V+DPX7q2e2K57ImqNBdfGHDIWaGI5xHxZoxbKOuQZn4wzPiUxOAHnsUr3w3xHrWXwN7gnG/iIuEMIg== 72 | 73 | "@types/connect@^3.4.33": 74 | version "3.4.35" 75 | resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.35.tgz#5fcf6ae445e4021d1fc2219a4873cc73a3bb2ad1" 76 | integrity sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ== 77 | dependencies: 78 | "@types/node" "*" 79 | 80 | "@types/node@*": 81 | version "18.11.9" 82 | resolved "https://registry.yarnpkg.com/@types/node/-/node-18.11.9.tgz#02d013de7058cea16d36168ef2fc653464cfbad4" 83 | integrity sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg== 84 | 85 | "@types/node@^12.12.54": 86 | version "12.20.55" 87 | resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.55.tgz#c329cbd434c42164f846b909bd6f85b5537f6240" 88 | integrity sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ== 89 | 90 | "@types/ws@^7.4.4": 91 | version "7.4.7" 92 | resolved "https://registry.yarnpkg.com/@types/ws/-/ws-7.4.7.tgz#f7c390a36f7a0679aa69de2d501319f4f8d9b702" 93 | integrity sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww== 94 | dependencies: 95 | "@types/node" "*" 96 | 97 | JSONStream@^1.3.5: 98 | version "1.3.5" 99 | resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.5.tgz#3208c1f08d3a4d99261ab64f92302bc15e111ca0" 100 | integrity sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ== 101 | dependencies: 102 | jsonparse "^1.2.0" 103 | through ">=2.2.7 <3" 104 | 105 | base-x@^4.0.0: 106 | version "4.0.0" 107 | resolved "https://registry.yarnpkg.com/base-x/-/base-x-4.0.0.tgz#d0e3b7753450c73f8ad2389b5c018a4af7b2224a" 108 | integrity sha512-FuwxlW4H5kh37X/oW59pwTzzTKRzfrrQwhmyspRM7swOEZcHtDZSCt45U6oKgtuFE+WYPblePMVIPR4RZrh/hw== 109 | 110 | bs58@^5.0.0: 111 | version "5.0.0" 112 | resolved "https://registry.yarnpkg.com/bs58/-/bs58-5.0.0.tgz#865575b4d13c09ea2a84622df6c8cbeb54ffc279" 113 | integrity sha512-r+ihvQJvahgYT50JD05dyJNKlmmSlMoOGwn1lCcEzanPglg7TxYjioQUYehQ9mAR/+hOSd2jRc/Z2y5UxBymvQ== 114 | dependencies: 115 | base-x "^4.0.0" 116 | 117 | bufferutil@^4.0.1: 118 | version "4.0.7" 119 | resolved "https://registry.yarnpkg.com/bufferutil/-/bufferutil-4.0.7.tgz#60c0d19ba2c992dd8273d3f73772ffc894c153ad" 120 | integrity sha512-kukuqc39WOHtdxtw4UScxF/WVnMFVSQVKhtx3AjZJzhd0RGZZldcrfSEbVsWWe6KNH253574cq5F+wpv0G9pJw== 121 | dependencies: 122 | node-gyp-build "^4.3.0" 123 | 124 | commander@^2.20.3: 125 | version "2.20.3" 126 | resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" 127 | integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== 128 | 129 | cross-fetch@^3.1.5: 130 | version "3.1.5" 131 | resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.5.tgz#e1389f44d9e7ba767907f7af8454787952ab534f" 132 | integrity sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw== 133 | dependencies: 134 | node-fetch "2.6.7" 135 | 136 | delay@^5.0.0: 137 | version "5.0.0" 138 | resolved "https://registry.yarnpkg.com/delay/-/delay-5.0.0.tgz#137045ef1b96e5071060dd5be60bf9334436bd1d" 139 | integrity sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw== 140 | 141 | es6-promise@^4.0.3: 142 | version "4.2.8" 143 | resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a" 144 | integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w== 145 | 146 | es6-promisify@^5.0.0: 147 | version "5.0.0" 148 | resolved "https://registry.yarnpkg.com/es6-promisify/-/es6-promisify-5.0.0.tgz#5109d62f3e56ea967c4b63505aef08291c8a5203" 149 | integrity sha512-C+d6UdsYDk0lMebHNR4S2NybQMMngAOnOwYBQjTOiv0MkoJMP0Myw2mgpDLBcpfCmRLxyFqYhS/CfOENq4SJhQ== 150 | dependencies: 151 | es6-promise "^4.0.3" 152 | 153 | eventemitter3@^4.0.7: 154 | version "4.0.7" 155 | resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" 156 | integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== 157 | 158 | eyes@^0.1.8: 159 | version "0.1.8" 160 | resolved "https://registry.yarnpkg.com/eyes/-/eyes-0.1.8.tgz#62cf120234c683785d902348a800ef3e0cc20bc0" 161 | integrity sha512-GipyPsXO1anza0AOZdy69Im7hGFCNB7Y/NGjDlZGJ3GJJLtwNSb2vrzYrTYJRrRloVx7pl+bhUaTB8yiccPvFQ== 162 | 163 | isomorphic-ws@^4.0.1: 164 | version "4.0.1" 165 | resolved "https://registry.yarnpkg.com/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz#55fd4cd6c5e6491e76dc125938dd863f5cd4f2dc" 166 | integrity sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w== 167 | 168 | jayson@^3.6.6: 169 | version "3.7.0" 170 | resolved "https://registry.yarnpkg.com/jayson/-/jayson-3.7.0.tgz#b735b12d06d348639ae8230d7a1e2916cb078f25" 171 | integrity sha512-tfy39KJMrrXJ+mFcMpxwBvFDetS8LAID93+rycFglIQM4kl3uNR3W4lBLE/FFhsoUCEox5Dt2adVpDm/XtebbQ== 172 | dependencies: 173 | "@types/connect" "^3.4.33" 174 | "@types/node" "^12.12.54" 175 | "@types/ws" "^7.4.4" 176 | JSONStream "^1.3.5" 177 | commander "^2.20.3" 178 | delay "^5.0.0" 179 | es6-promisify "^5.0.0" 180 | eyes "^0.1.8" 181 | isomorphic-ws "^4.0.1" 182 | json-stringify-safe "^5.0.1" 183 | lodash "^4.17.20" 184 | uuid "^8.3.2" 185 | ws "^7.4.5" 186 | 187 | js-sha3@^0.8.0: 188 | version "0.8.0" 189 | resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.8.0.tgz#b9b7a5da73afad7dedd0f8c463954cbde6818840" 190 | integrity sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q== 191 | 192 | json-stringify-safe@^5.0.1: 193 | version "5.0.1" 194 | resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" 195 | integrity sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA== 196 | 197 | jsonparse@^1.2.0: 198 | version "1.3.1" 199 | resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280" 200 | integrity sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg== 201 | 202 | lodash@^4.17.20: 203 | version "4.17.21" 204 | resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" 205 | integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== 206 | 207 | node-fetch@2.6.7: 208 | version "2.6.7" 209 | resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad" 210 | integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ== 211 | dependencies: 212 | whatwg-url "^5.0.0" 213 | 214 | node-gyp-build@^4.3.0: 215 | version "4.5.0" 216 | resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.5.0.tgz#7a64eefa0b21112f89f58379da128ac177f20e40" 217 | integrity sha512-2iGbaQBV+ITgCz76ZEjmhUKAKVf7xfY1sRl4UiKQspfZMH2h06SyhNsnSVy50cwkFQDGLyif6m/6uFXHkOZ6rg== 218 | 219 | regenerator-runtime@^0.13.10: 220 | version "0.13.11" 221 | resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9" 222 | integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg== 223 | 224 | rpc-websockets@^7.5.0: 225 | version "7.5.0" 226 | resolved "https://registry.yarnpkg.com/rpc-websockets/-/rpc-websockets-7.5.0.tgz#bbeb87572e66703ff151e50af1658f98098e2748" 227 | integrity sha512-9tIRi1uZGy7YmDjErf1Ax3wtqdSSLIlnmL5OtOzgd5eqPKbsPpwDP5whUDO2LQay3Xp0CcHlcNSGzacNRluBaQ== 228 | dependencies: 229 | "@babel/runtime" "^7.17.2" 230 | eventemitter3 "^4.0.7" 231 | uuid "^8.3.2" 232 | ws "^8.5.0" 233 | optionalDependencies: 234 | bufferutil "^4.0.1" 235 | utf-8-validate "^5.0.2" 236 | 237 | superstruct@^1.0.3: 238 | version "1.0.3" 239 | resolved "https://registry.yarnpkg.com/superstruct/-/superstruct-1.0.3.tgz#de626a5b49c6641ff4d37da3c7598e7a87697046" 240 | integrity sha512-8iTn3oSS8nRGn+C2pgXSKPI3jmpm6FExNazNpjvqS6ZUJQCej3PUXEKM8NjHBOs54ExM+LPW/FBRhymrdcCiSg== 241 | 242 | "through@>=2.2.7 <3": 243 | version "2.3.8" 244 | resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" 245 | integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg== 246 | 247 | tr46@~0.0.3: 248 | version "0.0.3" 249 | resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" 250 | integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== 251 | 252 | ts-retry-promise@^0.7.0: 253 | version "0.7.0" 254 | resolved "https://registry.yarnpkg.com/ts-retry-promise/-/ts-retry-promise-0.7.0.tgz#08f2dcbbf5d2981495841cb63389a268324e8147" 255 | integrity sha512-x6yWZXC4BfXy4UyMweOFvbS1yJ/Y5biSz/mEPiILtJZLrqD3ZxIpzVOGGgifHHdaSe3WxzFRtsRbychI6zofOg== 256 | 257 | tweetnacl@^1.0.3: 258 | version "1.0.3" 259 | resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-1.0.3.tgz#ac0af71680458d8a6378d0d0d050ab1407d35596" 260 | integrity sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw== 261 | 262 | utf-8-validate@^5.0.2: 263 | version "5.0.10" 264 | resolved "https://registry.yarnpkg.com/utf-8-validate/-/utf-8-validate-5.0.10.tgz#d7d10ea39318171ca982718b6b96a8d2442571a2" 265 | integrity sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ== 266 | dependencies: 267 | node-gyp-build "^4.3.0" 268 | 269 | uuid@^8.3.2: 270 | version "8.3.2" 271 | resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" 272 | integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== 273 | 274 | webidl-conversions@^3.0.0: 275 | version "3.0.1" 276 | resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" 277 | integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== 278 | 279 | whatwg-url@^5.0.0: 280 | version "5.0.0" 281 | resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" 282 | integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== 283 | dependencies: 284 | tr46 "~0.0.3" 285 | webidl-conversions "^3.0.0" 286 | 287 | ws@^7.4.5: 288 | version "7.5.9" 289 | resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.9.tgz#54fa7db29f4c7cec68b1ddd3a89de099942bb591" 290 | integrity sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q== 291 | 292 | ws@^8.5.0: 293 | version "8.11.0" 294 | resolved "https://registry.yarnpkg.com/ws/-/ws-8.11.0.tgz#6a0d36b8edfd9f96d8b25683db2f8d7de6e8e143" 295 | integrity sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg== 296 | -------------------------------------------------------------------------------- /sui-vector/Move.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "sui-vector" 3 | version = "0.0.1" 4 | 5 | [dependencies] 6 | Sui = { local = "../../sui/crates/sui-framework/packages/sui-framework" } 7 | -------------------------------------------------------------------------------- /sui-vector/README.md: -------------------------------------------------------------------------------- 1 | # cmd 2 | 3 | ```move 4 | module 0x0::vector { 5 | use std::vector; 6 | use sui::coin::Coin; 7 | use sui::sui::SUI; 8 | use sui::pay; 9 | 10 | public entry fun vec( 11 | self: &mut Coin, 12 | vec_bool: vector, 13 | vec_u8: vector, 14 | vec_u64: vector, 15 | vec_address: vector
, 16 | vec_coins: vector> 17 | ) { 18 | assert!(vector::length(&vec_bool) > 0, 1); 19 | assert!(vector::length(&vec_u8) > 0, 2); 20 | assert!(vector::length(&vec_u64) > 0, 3); 21 | assert!(vector::length(&vec_address) > 0, 4); 22 | 23 | pay::join_vec(self, vec_coins) 24 | } 25 | } 26 | ``` 27 | 28 | ```bash 29 | sui client publish --gas-budget 10000 30 | package=0xce6cab8be08edcfb12e2f26c2ac288de35a0b9a6 31 | sui_coin1=0xdbdae62c692525b893b33e413664946ef07ef30c 32 | sui_coin2=0xccfe11e303b81749a2c3a1288e73e4cf88843844 33 | sui_coin3=0xb24e1287006d04acc2526cd058ba916094120472 34 | sui_coin4=0x50db356f3d971ac5e15bb2c87076eb3185baf388 35 | 36 | sui client call \ 37 | --gas-budget 10000 \ 38 | --package $package \ 39 | --module vector \ 40 | --function vec \ 41 | --args $sui_coin1 \ 42 | '[true]' \ 43 | '[0, 1]' \ 44 | '[78, 89, 32]' \ 45 | '["0xb811881d75c77acec51ff1622a3cc1bd6b247707"]' \ 46 | "[\"$sui_coin2\"]" 47 | 48 | sui client call \ 49 | --gas-budget 10000 \ 50 | --package $package \ 51 | --module vector \ 52 | --function vec \ 53 | --args $sui_coin1 \ 54 | '[true]' \ 55 | '0x1234' \ 56 | '[78, 89, 32]' \ 57 | '["0xb811881d75c77acec51ff1622a3cc1bd6b247707"]' \ 58 | "[\"$sui_coin3\"]" 59 | 60 | sui client call \ 61 | --gas-budget 10000 \ 62 | --package $package \ 63 | --module vector \ 64 | --function vec \ 65 | --args $sui_coin1 \ 66 | '[true, false]' \ 67 | 'test' \ 68 | '[78, 89, 32]' \ 69 | '["0xb811881d75c77acec51ff1622a3cc1bd6b247707", "0xa52f14e21c49d03f7a9e615c3bb56bb3de926b92"]' \ 70 | "[\"$sui_coin4\"]" 71 | 72 | ``` 73 | 74 | [sui-json vector](https://github.com/MystenLabs/sui/blob/main/crates/sui-json/src/lib.rs#L209-L245) 75 | ```rust 76 | (JsonValue::String(s), MoveTypeLayout::Vector(t)) => { 77 | match &**t { 78 | MoveTypeLayout::U8 => { 79 | // We can encode U8 Vector as string in 2 ways 80 | // 1. If it starts with 0x, we treat it as hex strings, where each pair is a 81 | // byte 82 | // 2. If it does not start with 0x, we treat each character as an ASCII 83 | // encoded byte 84 | // We have to support both for the convenience of the user. This is because 85 | // sometime we need Strings as arg Other times we need vec of hex bytes for 86 | // address. Issue is both Address and Strings are represented as Vec in 87 | // Move call 88 | let vec = if s.starts_with(HEX_PREFIX) { 89 | // If starts with 0x, treat as hex vector 90 | Hex::decode(s).map_err(|e| anyhow!(e))? 91 | } else { 92 | // Else raw bytes 93 | s.as_bytes().to_vec() 94 | }; 95 | MoveValue::Vector(vec.iter().copied().map(MoveValue::U8).collect()) 96 | } 97 | MoveTypeLayout::Struct(MoveStructLayout::Runtime(inner)) => { 98 | Self::handle_inner_struct_layout(inner, val, ty, s)? 99 | } 100 | _ => bail!("Cannot convert string arg {s} to {ty}"), 101 | } 102 | } 103 | 104 | // We have already checked that the array is homogeneous in the constructor 105 | (JsonValue::Array(a), MoveTypeLayout::Vector(inner)) => { 106 | // Recursively build an IntermediateValue array 107 | MoveValue::Vector( 108 | a.iter() 109 | .map(|i| Self::to_move_value(i, inner)) 110 | .collect::, _>>()?, 111 | ) 112 | } 113 | ``` 114 | 115 | 116 | # sui typejs sdk 117 | 118 | ```bash 119 | ts-node ./call.ts 120 | ``` -------------------------------------------------------------------------------- /sui-vector/call.ts: -------------------------------------------------------------------------------- 1 | import { 2 | Ed25519Keypair, 3 | JsonRpcProvider, 4 | RawSigner, 5 | TransactionBlock, 6 | testnetConnection, 7 | bcs 8 | } from '@mysten/sui.js'; 9 | 10 | async function main() { 11 | 12 | const privkey = process.env.PRIVKEY ?? "empty" 13 | console.log("privkey:", Buffer.from(privkey, "hex").toString("hex")) 14 | 15 | const keypair = Ed25519Keypair.fromSecretKey(Uint8Array.from(Buffer.from(privkey, "hex"))) 16 | 17 | const provider = new JsonRpcProvider(testnetConnection); 18 | const signer = new RawSigner(keypair, provider); 19 | const txb = new TransactionBlock(); 20 | 21 | // https://github.com/MystenLabs/sui/blob/main/crates/sui-protocol-config/src/lib.rs#L746 22 | const max_pure_argument_size = 16 * 1024 23 | 24 | let vec_address: string[] = [] 25 | for (var i=0; i < 500; i++) { 26 | vec_address.push("0x28b140d21386129f4e08380cadbbd560df92e01b28a53fc96d97464f384d923b") 27 | } 28 | 29 | const vec_address_bytes = bcs.ser('vector
', vec_address, {maxSize: max_pure_argument_size}).toBytes() 30 | 31 | const vec_u8_bytes = Array.from(Buffer.from("中文字体", "utf8")) 32 | 33 | const coins = txb.splitCoins( 34 | txb.gas, 35 | [txb.pure(1000), txb.pure(2000)] 36 | ) 37 | 38 | // public entry fun vec( 39 | // self: &mut Coin, 40 | // vec_bool: vector, 41 | // vec_u8: vector, 42 | // vec_u64: vector, 43 | // vec_address: vector
, 44 | // vec_coins: vector> 45 | // ) 46 | txb.moveCall( 47 | { 48 | target: "0x28b140d21386129f4e08380cadbbd560df92e01b28a53fc96d97464f384d923b::vector::vec", 49 | arguments: [ 50 | txb.gas, 51 | txb.pure([true, false, true], 'vector'), 52 | txb.pure(vec_u8_bytes), 53 | txb.pure([1,2,3], 'vector'), 54 | txb.pure(vec_address_bytes), 55 | txb.makeMoveVec({objects: [coins[0], coins[1]]}) 56 | ] 57 | } 58 | ); 59 | 60 | const result = await signer.signAndExecuteTransactionBlock({ 61 | transactionBlock: txb, 62 | }); 63 | console.log({ result }); 64 | } 65 | 66 | // We recommend this pattern to be able to use async/await everywhere 67 | // and properly handle errors. 68 | main().catch((error) => { 69 | console.error(error); 70 | process.exitCode = 1; 71 | }); 72 | -------------------------------------------------------------------------------- /sui-vector/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "@mysten/sui.js": "0.32.1", 4 | "dotenv": "^16.0.3" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /sui-vector/sources/vector.move: -------------------------------------------------------------------------------- 1 | module 0x0::vector { 2 | use std::vector; 3 | use sui::coin::Coin; 4 | use sui::sui::SUI; 5 | use sui::pay; 6 | 7 | public entry fun vec( 8 | self: &mut Coin, 9 | vec_bool: vector, 10 | vec_u8: vector, 11 | vec_u64: vector, 12 | vec_address: vector
, 13 | vec_coins: vector> 14 | ) { 15 | assert!(vector::length(&vec_bool) > 0, 1); 16 | assert!(vector::length(&vec_u8) > 0, 2); 17 | assert!(vector::length(&vec_u64) > 0, 3); 18 | assert!(vector::length(&vec_address) > 0, 4); 19 | 20 | pay::join_vec(self, vec_coins) 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /sui-vector/yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@babel/runtime@^7.17.2": 6 | version "7.21.0" 7 | resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.21.0.tgz#5b55c9d394e5fcf304909a8b00c07dc217b56673" 8 | integrity sha512-xwII0//EObnq89Ji5AKYQaRYiW/nZ3llSv29d49IuxPhKbtJoLP+9QUUZ4nVragQVtaVGeZrpB+ZtG/Pdy/POw== 9 | dependencies: 10 | regenerator-runtime "^0.13.11" 11 | 12 | "@mswjs/cookies@^0.2.2": 13 | version "0.2.2" 14 | resolved "https://registry.yarnpkg.com/@mswjs/cookies/-/cookies-0.2.2.tgz#b4e207bf6989e5d5427539c2443380a33ebb922b" 15 | integrity sha512-mlN83YSrcFgk7Dm1Mys40DLssI1KdJji2CMKN8eOlBqsTADYzj2+jWzsANsUTFbxDMWPD5e9bfA1RGqBpS3O1g== 16 | dependencies: 17 | "@types/set-cookie-parser" "^2.4.0" 18 | set-cookie-parser "^2.4.6" 19 | 20 | "@mswjs/interceptors@^0.17.5": 21 | version "0.17.9" 22 | resolved "https://registry.yarnpkg.com/@mswjs/interceptors/-/interceptors-0.17.9.tgz#0096fc88fea63ee42e36836acae8f4ae33651c04" 23 | integrity sha512-4LVGt03RobMH/7ZrbHqRxQrS9cc2uh+iNKSj8UWr8M26A2i793ju+csaB5zaqYltqJmA2jUq4VeYfKmVqvsXQg== 24 | dependencies: 25 | "@open-draft/until" "^1.0.3" 26 | "@types/debug" "^4.1.7" 27 | "@xmldom/xmldom" "^0.8.3" 28 | debug "^4.3.3" 29 | headers-polyfill "^3.1.0" 30 | outvariant "^1.2.1" 31 | strict-event-emitter "^0.2.4" 32 | web-encoding "^1.1.5" 33 | 34 | "@mysten/bcs@0.7.0": 35 | version "0.7.0" 36 | resolved "https://registry.yarnpkg.com/@mysten/bcs/-/bcs-0.7.0.tgz#141cbaba8ccb89215747d9ca1296c20c5b4fe4a1" 37 | integrity sha512-AFNnTClmc1XuxWZOzrzqVPDnujgN5AF2oNUyPYbLfvwqAj+qH7CrE3Rxhuf7et+k8M1Ff55CDgF58vPDMIhIrA== 38 | dependencies: 39 | bs58 "^5.0.0" 40 | 41 | "@mysten/sui.js@0.32.1": 42 | version "0.32.1" 43 | resolved "https://registry.yarnpkg.com/@mysten/sui.js/-/sui.js-0.32.1.tgz#d1ba3f324ef3335abde352be5d5fea131b9196ba" 44 | integrity sha512-HD3D/3g//dx5e/1W42krEv4+Zl5PP0faH229jFOhnOktIRGxRrDfb6eU2+juclTug2e68JseTiX2QulIh+2/FQ== 45 | dependencies: 46 | "@mysten/bcs" "0.7.0" 47 | "@noble/curves" "^0.9.0" 48 | "@noble/hashes" "^1.3.0" 49 | "@scure/bip32" "^1.2.0" 50 | "@scure/bip39" "^1.2.0" 51 | "@suchipi/femver" "^1.0.0" 52 | jayson "^4.0.0" 53 | msw "^1.2.1" 54 | rpc-websockets "^7.5.1" 55 | superstruct "^1.0.3" 56 | tweetnacl "^1.0.3" 57 | 58 | "@noble/curves@^0.9.0": 59 | version "0.9.1" 60 | resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-0.9.1.tgz#0ad33ebee0fdc870e1afcd74daa06f188e89b8fe" 61 | integrity sha512-SpO5TViHvyBV8RrvGejzzl0+wbSm21q+hC6ZmK5NtqOjigR+WW9OohvKL0M3EHKvWzqaZ5Z7F46ejxAVDTBnvQ== 62 | dependencies: 63 | "@noble/hashes" "1.3.0" 64 | 65 | "@noble/curves@~1.0.0": 66 | version "1.0.0" 67 | resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.0.0.tgz#e40be8c7daf088aaf291887cbc73f43464a92932" 68 | integrity sha512-2upgEu0iLiDVDZkNLeFV2+ht0BAVgQnEmCk6JsOch9Rp8xfkMCbvbAZlA2pBHQc73dbl+vFOXfqkf4uemdn0bw== 69 | dependencies: 70 | "@noble/hashes" "1.3.0" 71 | 72 | "@noble/hashes@1.3.0", "@noble/hashes@^1.3.0", "@noble/hashes@~1.3.0": 73 | version "1.3.0" 74 | resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.0.tgz#085fd70f6d7d9d109671090ccae1d3bec62554a1" 75 | integrity sha512-ilHEACi9DwqJB0pw7kv+Apvh50jiiSyR/cQ3y4W7lOR5mhvn/50FLUfsnfJz0BDZtl/RR16kXvptiv6q1msYZg== 76 | 77 | "@open-draft/until@^1.0.3": 78 | version "1.0.3" 79 | resolved "https://registry.yarnpkg.com/@open-draft/until/-/until-1.0.3.tgz#db9cc719191a62e7d9200f6e7bab21c5b848adca" 80 | integrity sha512-Aq58f5HiWdyDlFffbbSjAlv596h/cOnt2DO1w3DOC7OJ5EHs0hd/nycJfiu9RJbT6Yk6F1knnRRXNSpxoIVZ9Q== 81 | 82 | "@scure/base@~1.1.0": 83 | version "1.1.1" 84 | resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.1.1.tgz#ebb651ee52ff84f420097055f4bf46cfba403938" 85 | integrity sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA== 86 | 87 | "@scure/bip32@^1.2.0": 88 | version "1.3.0" 89 | resolved "https://registry.yarnpkg.com/@scure/bip32/-/bip32-1.3.0.tgz#6c8d980ef3f290987736acd0ee2e0f0d50068d87" 90 | integrity sha512-bcKpo1oj54hGholplGLpqPHRbIsnbixFtc06nwuNM5/dwSXOq/AAYoIBRsBmnZJSdfeNW5rnff7NTAz3ZCqR9Q== 91 | dependencies: 92 | "@noble/curves" "~1.0.0" 93 | "@noble/hashes" "~1.3.0" 94 | "@scure/base" "~1.1.0" 95 | 96 | "@scure/bip39@^1.2.0": 97 | version "1.2.0" 98 | resolved "https://registry.yarnpkg.com/@scure/bip39/-/bip39-1.2.0.tgz#a207e2ef96de354de7d0002292ba1503538fc77b" 99 | integrity sha512-SX/uKq52cuxm4YFXWFaVByaSHJh2w3BnokVSeUJVCv6K7WulT9u2BuNRBhuFl8vAuYnzx9bEu9WgpcNYTrYieg== 100 | dependencies: 101 | "@noble/hashes" "~1.3.0" 102 | "@scure/base" "~1.1.0" 103 | 104 | "@suchipi/femver@^1.0.0": 105 | version "1.0.0" 106 | resolved "https://registry.yarnpkg.com/@suchipi/femver/-/femver-1.0.0.tgz#4909dcc069695e07bd23a64c4bfe411d11d9692f" 107 | integrity sha512-bprE8+K5V+DPX7q2e2K57ImqNBdfGHDIWaGI5xHxZoxbKOuQZn4wzPiUxOAHnsUr3w3xHrWXwN7gnG/iIuEMIg== 108 | 109 | "@types/connect@^3.4.33": 110 | version "3.4.35" 111 | resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.35.tgz#5fcf6ae445e4021d1fc2219a4873cc73a3bb2ad1" 112 | integrity sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ== 113 | dependencies: 114 | "@types/node" "*" 115 | 116 | "@types/cookie@^0.4.1": 117 | version "0.4.1" 118 | resolved "https://registry.yarnpkg.com/@types/cookie/-/cookie-0.4.1.tgz#bfd02c1f2224567676c1545199f87c3a861d878d" 119 | integrity sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q== 120 | 121 | "@types/debug@^4.1.7": 122 | version "4.1.7" 123 | resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.7.tgz#7cc0ea761509124709b8b2d1090d8f6c17aadb82" 124 | integrity sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg== 125 | dependencies: 126 | "@types/ms" "*" 127 | 128 | "@types/js-levenshtein@^1.1.1": 129 | version "1.1.1" 130 | resolved "https://registry.yarnpkg.com/@types/js-levenshtein/-/js-levenshtein-1.1.1.tgz#ba05426a43f9e4e30b631941e0aa17bf0c890ed5" 131 | integrity sha512-qC4bCqYGy1y/NP7dDVr7KJarn+PbX1nSpwA7JXdu0HxT3QYjO8MJ+cntENtHFVy2dRAyBV23OZ6MxsW1AM1L8g== 132 | 133 | "@types/ms@*": 134 | version "0.7.31" 135 | resolved "https://registry.yarnpkg.com/@types/ms/-/ms-0.7.31.tgz#31b7ca6407128a3d2bbc27fe2d21b345397f6197" 136 | integrity sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA== 137 | 138 | "@types/node@*": 139 | version "18.15.11" 140 | resolved "https://registry.yarnpkg.com/@types/node/-/node-18.15.11.tgz#b3b790f09cb1696cffcec605de025b088fa4225f" 141 | integrity sha512-E5Kwq2n4SbMzQOn6wnmBjuK9ouqlURrcZDVfbo9ftDDTFt3nk7ZKK4GMOzoYgnpQJKcxwQw+lGaBvvlMo0qN/Q== 142 | 143 | "@types/node@^12.12.54": 144 | version "12.20.55" 145 | resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.55.tgz#c329cbd434c42164f846b909bd6f85b5537f6240" 146 | integrity sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ== 147 | 148 | "@types/set-cookie-parser@^2.4.0": 149 | version "2.4.2" 150 | resolved "https://registry.yarnpkg.com/@types/set-cookie-parser/-/set-cookie-parser-2.4.2.tgz#b6a955219b54151bfebd4521170723df5e13caad" 151 | integrity sha512-fBZgytwhYAUkj/jC/FAV4RQ5EerRup1YQsXQCh8rZfiHkc4UahC192oH0smGwsXol3cL3A5oETuAHeQHmhXM4w== 152 | dependencies: 153 | "@types/node" "*" 154 | 155 | "@types/ws@^7.4.4": 156 | version "7.4.7" 157 | resolved "https://registry.yarnpkg.com/@types/ws/-/ws-7.4.7.tgz#f7c390a36f7a0679aa69de2d501319f4f8d9b702" 158 | integrity sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww== 159 | dependencies: 160 | "@types/node" "*" 161 | 162 | "@xmldom/xmldom@^0.8.3": 163 | version "0.8.7" 164 | resolved "https://registry.yarnpkg.com/@xmldom/xmldom/-/xmldom-0.8.7.tgz#8b1e39c547013941974d83ad5e9cf5042071a9a0" 165 | integrity sha512-sI1Ly2cODlWStkINzqGrZ8K6n+MTSbAeQnAipGyL+KZCXuHaRlj2gyyy8B/9MvsFFqN7XHryQnB2QwhzvJXovg== 166 | 167 | "@zxing/text-encoding@0.9.0": 168 | version "0.9.0" 169 | resolved "https://registry.yarnpkg.com/@zxing/text-encoding/-/text-encoding-0.9.0.tgz#fb50ffabc6c7c66a0c96b4c03e3d9be74864b70b" 170 | integrity sha512-U/4aVJ2mxI0aDNI8Uq0wEhMgY+u4CNtEb0om3+y3+niDAsoTCOB33UF0sxpzqzdqXLqmvc+vZyAt4O8pPdfkwA== 171 | 172 | JSONStream@^1.3.5: 173 | version "1.3.5" 174 | resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.5.tgz#3208c1f08d3a4d99261ab64f92302bc15e111ca0" 175 | integrity sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ== 176 | dependencies: 177 | jsonparse "^1.2.0" 178 | through ">=2.2.7 <3" 179 | 180 | ansi-escapes@^4.2.1: 181 | version "4.3.2" 182 | resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" 183 | integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== 184 | dependencies: 185 | type-fest "^0.21.3" 186 | 187 | ansi-regex@^5.0.1: 188 | version "5.0.1" 189 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" 190 | integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== 191 | 192 | ansi-styles@^4.0.0, ansi-styles@^4.1.0: 193 | version "4.3.0" 194 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" 195 | integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== 196 | dependencies: 197 | color-convert "^2.0.1" 198 | 199 | anymatch@~3.1.2: 200 | version "3.1.3" 201 | resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" 202 | integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== 203 | dependencies: 204 | normalize-path "^3.0.0" 205 | picomatch "^2.0.4" 206 | 207 | available-typed-arrays@^1.0.5: 208 | version "1.0.5" 209 | resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7" 210 | integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== 211 | 212 | base-x@^4.0.0: 213 | version "4.0.0" 214 | resolved "https://registry.yarnpkg.com/base-x/-/base-x-4.0.0.tgz#d0e3b7753450c73f8ad2389b5c018a4af7b2224a" 215 | integrity sha512-FuwxlW4H5kh37X/oW59pwTzzTKRzfrrQwhmyspRM7swOEZcHtDZSCt45U6oKgtuFE+WYPblePMVIPR4RZrh/hw== 216 | 217 | base64-js@^1.3.1: 218 | version "1.5.1" 219 | resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" 220 | integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== 221 | 222 | binary-extensions@^2.0.0: 223 | version "2.2.0" 224 | resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" 225 | integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== 226 | 227 | bl@^4.1.0: 228 | version "4.1.0" 229 | resolved "https://registry.yarnpkg.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a" 230 | integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w== 231 | dependencies: 232 | buffer "^5.5.0" 233 | inherits "^2.0.4" 234 | readable-stream "^3.4.0" 235 | 236 | braces@~3.0.2: 237 | version "3.0.2" 238 | resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" 239 | integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== 240 | dependencies: 241 | fill-range "^7.0.1" 242 | 243 | bs58@^5.0.0: 244 | version "5.0.0" 245 | resolved "https://registry.yarnpkg.com/bs58/-/bs58-5.0.0.tgz#865575b4d13c09ea2a84622df6c8cbeb54ffc279" 246 | integrity sha512-r+ihvQJvahgYT50JD05dyJNKlmmSlMoOGwn1lCcEzanPglg7TxYjioQUYehQ9mAR/+hOSd2jRc/Z2y5UxBymvQ== 247 | dependencies: 248 | base-x "^4.0.0" 249 | 250 | buffer@^5.5.0: 251 | version "5.7.1" 252 | resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" 253 | integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== 254 | dependencies: 255 | base64-js "^1.3.1" 256 | ieee754 "^1.1.13" 257 | 258 | bufferutil@^4.0.1: 259 | version "4.0.7" 260 | resolved "https://registry.yarnpkg.com/bufferutil/-/bufferutil-4.0.7.tgz#60c0d19ba2c992dd8273d3f73772ffc894c153ad" 261 | integrity sha512-kukuqc39WOHtdxtw4UScxF/WVnMFVSQVKhtx3AjZJzhd0RGZZldcrfSEbVsWWe6KNH253574cq5F+wpv0G9pJw== 262 | dependencies: 263 | node-gyp-build "^4.3.0" 264 | 265 | call-bind@^1.0.2: 266 | version "1.0.2" 267 | resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" 268 | integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== 269 | dependencies: 270 | function-bind "^1.1.1" 271 | get-intrinsic "^1.0.2" 272 | 273 | chalk@4.1.1: 274 | version "4.1.1" 275 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.1.tgz#c80b3fab28bf6371e6863325eee67e618b77e6ad" 276 | integrity sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg== 277 | dependencies: 278 | ansi-styles "^4.1.0" 279 | supports-color "^7.1.0" 280 | 281 | chalk@^4.1.0, chalk@^4.1.1: 282 | version "4.1.2" 283 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" 284 | integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== 285 | dependencies: 286 | ansi-styles "^4.1.0" 287 | supports-color "^7.1.0" 288 | 289 | chardet@^0.7.0: 290 | version "0.7.0" 291 | resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" 292 | integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== 293 | 294 | chokidar@^3.4.2: 295 | version "3.5.3" 296 | resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" 297 | integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== 298 | dependencies: 299 | anymatch "~3.1.2" 300 | braces "~3.0.2" 301 | glob-parent "~5.1.2" 302 | is-binary-path "~2.1.0" 303 | is-glob "~4.0.1" 304 | normalize-path "~3.0.0" 305 | readdirp "~3.6.0" 306 | optionalDependencies: 307 | fsevents "~2.3.2" 308 | 309 | cli-cursor@^3.1.0: 310 | version "3.1.0" 311 | resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307" 312 | integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw== 313 | dependencies: 314 | restore-cursor "^3.1.0" 315 | 316 | cli-spinners@^2.5.0: 317 | version "2.8.0" 318 | resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.8.0.tgz#e97a3e2bd00e6d85aa0c13d7f9e3ce236f7787fc" 319 | integrity sha512-/eG5sJcvEIwxcdYM86k5tPwn0MUzkX5YY3eImTGpJOZgVe4SdTMY14vQpcxgBzJ0wXwAYrS8E+c3uHeK4JNyzQ== 320 | 321 | cli-width@^3.0.0: 322 | version "3.0.0" 323 | resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-3.0.0.tgz#a2f48437a2caa9a22436e794bf071ec9e61cedf6" 324 | integrity sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw== 325 | 326 | cliui@^8.0.1: 327 | version "8.0.1" 328 | resolved "https://registry.yarnpkg.com/cliui/-/cliui-8.0.1.tgz#0c04b075db02cbfe60dc8e6cf2f5486b1a3608aa" 329 | integrity sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ== 330 | dependencies: 331 | string-width "^4.2.0" 332 | strip-ansi "^6.0.1" 333 | wrap-ansi "^7.0.0" 334 | 335 | clone@^1.0.2: 336 | version "1.0.4" 337 | resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" 338 | integrity sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg== 339 | 340 | color-convert@^2.0.1: 341 | version "2.0.1" 342 | resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" 343 | integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== 344 | dependencies: 345 | color-name "~1.1.4" 346 | 347 | color-name@~1.1.4: 348 | version "1.1.4" 349 | resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" 350 | integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== 351 | 352 | commander@^2.20.3: 353 | version "2.20.3" 354 | resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" 355 | integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== 356 | 357 | cookie@^0.4.2: 358 | version "0.4.2" 359 | resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.2.tgz#0e41f24de5ecf317947c82fc789e06a884824432" 360 | integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA== 361 | 362 | debug@^4.3.3: 363 | version "4.3.4" 364 | resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" 365 | integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== 366 | dependencies: 367 | ms "2.1.2" 368 | 369 | defaults@^1.0.3: 370 | version "1.0.4" 371 | resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.4.tgz#b0b02062c1e2aa62ff5d9528f0f98baa90978d7a" 372 | integrity sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A== 373 | dependencies: 374 | clone "^1.0.2" 375 | 376 | delay@^5.0.0: 377 | version "5.0.0" 378 | resolved "https://registry.yarnpkg.com/delay/-/delay-5.0.0.tgz#137045ef1b96e5071060dd5be60bf9334436bd1d" 379 | integrity sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw== 380 | 381 | dotenv@^16.0.3: 382 | version "16.0.3" 383 | resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.0.3.tgz#115aec42bac5053db3c456db30cc243a5a836a07" 384 | integrity sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ== 385 | 386 | emoji-regex@^8.0.0: 387 | version "8.0.0" 388 | resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" 389 | integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== 390 | 391 | es6-promise@^4.0.3: 392 | version "4.2.8" 393 | resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a" 394 | integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w== 395 | 396 | es6-promisify@^5.0.0: 397 | version "5.0.0" 398 | resolved "https://registry.yarnpkg.com/es6-promisify/-/es6-promisify-5.0.0.tgz#5109d62f3e56ea967c4b63505aef08291c8a5203" 399 | integrity sha512-C+d6UdsYDk0lMebHNR4S2NybQMMngAOnOwYBQjTOiv0MkoJMP0Myw2mgpDLBcpfCmRLxyFqYhS/CfOENq4SJhQ== 400 | dependencies: 401 | es6-promise "^4.0.3" 402 | 403 | escalade@^3.1.1: 404 | version "3.1.1" 405 | resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" 406 | integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== 407 | 408 | escape-string-regexp@^1.0.5: 409 | version "1.0.5" 410 | resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" 411 | integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== 412 | 413 | eventemitter3@^4.0.7: 414 | version "4.0.7" 415 | resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" 416 | integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== 417 | 418 | events@^3.3.0: 419 | version "3.3.0" 420 | resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" 421 | integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== 422 | 423 | external-editor@^3.0.3: 424 | version "3.1.0" 425 | resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495" 426 | integrity sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew== 427 | dependencies: 428 | chardet "^0.7.0" 429 | iconv-lite "^0.4.24" 430 | tmp "^0.0.33" 431 | 432 | eyes@^0.1.8: 433 | version "0.1.8" 434 | resolved "https://registry.yarnpkg.com/eyes/-/eyes-0.1.8.tgz#62cf120234c683785d902348a800ef3e0cc20bc0" 435 | integrity sha512-GipyPsXO1anza0AOZdy69Im7hGFCNB7Y/NGjDlZGJ3GJJLtwNSb2vrzYrTYJRrRloVx7pl+bhUaTB8yiccPvFQ== 436 | 437 | figures@^3.0.0: 438 | version "3.2.0" 439 | resolved "https://registry.yarnpkg.com/figures/-/figures-3.2.0.tgz#625c18bd293c604dc4a8ddb2febf0c88341746af" 440 | integrity sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg== 441 | dependencies: 442 | escape-string-regexp "^1.0.5" 443 | 444 | fill-range@^7.0.1: 445 | version "7.0.1" 446 | resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" 447 | integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== 448 | dependencies: 449 | to-regex-range "^5.0.1" 450 | 451 | for-each@^0.3.3: 452 | version "0.3.3" 453 | resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e" 454 | integrity sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw== 455 | dependencies: 456 | is-callable "^1.1.3" 457 | 458 | fsevents@~2.3.2: 459 | version "2.3.2" 460 | resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" 461 | integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== 462 | 463 | function-bind@^1.1.1: 464 | version "1.1.1" 465 | resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" 466 | integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== 467 | 468 | get-caller-file@^2.0.5: 469 | version "2.0.5" 470 | resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" 471 | integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== 472 | 473 | get-intrinsic@^1.0.2, get-intrinsic@^1.1.3: 474 | version "1.2.0" 475 | resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.0.tgz#7ad1dc0535f3a2904bba075772763e5051f6d05f" 476 | integrity sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q== 477 | dependencies: 478 | function-bind "^1.1.1" 479 | has "^1.0.3" 480 | has-symbols "^1.0.3" 481 | 482 | glob-parent@~5.1.2: 483 | version "5.1.2" 484 | resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" 485 | integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== 486 | dependencies: 487 | is-glob "^4.0.1" 488 | 489 | gopd@^1.0.1: 490 | version "1.0.1" 491 | resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c" 492 | integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA== 493 | dependencies: 494 | get-intrinsic "^1.1.3" 495 | 496 | "graphql@^15.0.0 || ^16.0.0": 497 | version "16.6.0" 498 | resolved "https://registry.yarnpkg.com/graphql/-/graphql-16.6.0.tgz#c2dcffa4649db149f6282af726c8c83f1c7c5fdb" 499 | integrity sha512-KPIBPDlW7NxrbT/eh4qPXz5FiFdL5UbaA0XUNz2Rp3Z3hqBSkbj0GVjwFDztsWVauZUWsbKHgMg++sk8UX0bkw== 500 | 501 | has-flag@^4.0.0: 502 | version "4.0.0" 503 | resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" 504 | integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== 505 | 506 | has-symbols@^1.0.2, has-symbols@^1.0.3: 507 | version "1.0.3" 508 | resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" 509 | integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== 510 | 511 | has-tostringtag@^1.0.0: 512 | version "1.0.0" 513 | resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25" 514 | integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== 515 | dependencies: 516 | has-symbols "^1.0.2" 517 | 518 | has@^1.0.3: 519 | version "1.0.3" 520 | resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" 521 | integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== 522 | dependencies: 523 | function-bind "^1.1.1" 524 | 525 | headers-polyfill@^3.1.0, headers-polyfill@^3.1.2: 526 | version "3.1.2" 527 | resolved "https://registry.yarnpkg.com/headers-polyfill/-/headers-polyfill-3.1.2.tgz#9a4dcb545c5b95d9569592ef7ec0708aab763fbe" 528 | integrity sha512-tWCK4biJ6hcLqTviLXVR9DTRfYGQMXEIUj3gwJ2rZ5wO/at3XtkI4g8mCvFdUF9l1KMBNCfmNAdnahm1cgavQA== 529 | 530 | iconv-lite@^0.4.24: 531 | version "0.4.24" 532 | resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" 533 | integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== 534 | dependencies: 535 | safer-buffer ">= 2.1.2 < 3" 536 | 537 | ieee754@^1.1.13: 538 | version "1.2.1" 539 | resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" 540 | integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== 541 | 542 | inherits@^2.0.3, inherits@^2.0.4: 543 | version "2.0.4" 544 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" 545 | integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== 546 | 547 | inquirer@^8.2.0: 548 | version "8.2.5" 549 | resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-8.2.5.tgz#d8654a7542c35a9b9e069d27e2df4858784d54f8" 550 | integrity sha512-QAgPDQMEgrDssk1XiwwHoOGYF9BAbUcc1+j+FhEvaOt8/cKRqyLn0U5qA6F74fGhTMGxf92pOvPBeh29jQJDTQ== 551 | dependencies: 552 | ansi-escapes "^4.2.1" 553 | chalk "^4.1.1" 554 | cli-cursor "^3.1.0" 555 | cli-width "^3.0.0" 556 | external-editor "^3.0.3" 557 | figures "^3.0.0" 558 | lodash "^4.17.21" 559 | mute-stream "0.0.8" 560 | ora "^5.4.1" 561 | run-async "^2.4.0" 562 | rxjs "^7.5.5" 563 | string-width "^4.1.0" 564 | strip-ansi "^6.0.0" 565 | through "^2.3.6" 566 | wrap-ansi "^7.0.0" 567 | 568 | is-arguments@^1.0.4: 569 | version "1.1.1" 570 | resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.1.tgz#15b3f88fda01f2a97fec84ca761a560f123efa9b" 571 | integrity sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA== 572 | dependencies: 573 | call-bind "^1.0.2" 574 | has-tostringtag "^1.0.0" 575 | 576 | is-binary-path@~2.1.0: 577 | version "2.1.0" 578 | resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" 579 | integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== 580 | dependencies: 581 | binary-extensions "^2.0.0" 582 | 583 | is-callable@^1.1.3: 584 | version "1.2.7" 585 | resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055" 586 | integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== 587 | 588 | is-extglob@^2.1.1: 589 | version "2.1.1" 590 | resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" 591 | integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== 592 | 593 | is-fullwidth-code-point@^3.0.0: 594 | version "3.0.0" 595 | resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" 596 | integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== 597 | 598 | is-generator-function@^1.0.7: 599 | version "1.0.10" 600 | resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.10.tgz#f1558baf1ac17e0deea7c0415c438351ff2b3c72" 601 | integrity sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A== 602 | dependencies: 603 | has-tostringtag "^1.0.0" 604 | 605 | is-glob@^4.0.1, is-glob@~4.0.1: 606 | version "4.0.3" 607 | resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" 608 | integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== 609 | dependencies: 610 | is-extglob "^2.1.1" 611 | 612 | is-interactive@^1.0.0: 613 | version "1.0.0" 614 | resolved "https://registry.yarnpkg.com/is-interactive/-/is-interactive-1.0.0.tgz#cea6e6ae5c870a7b0a0004070b7b587e0252912e" 615 | integrity sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w== 616 | 617 | is-node-process@^1.2.0: 618 | version "1.2.0" 619 | resolved "https://registry.yarnpkg.com/is-node-process/-/is-node-process-1.2.0.tgz#ea02a1b90ddb3934a19aea414e88edef7e11d134" 620 | integrity sha512-Vg4o6/fqPxIjtxgUH5QLJhwZ7gW5diGCVlXpuUfELC62CuxM1iHcRe51f2W1FDy04Ai4KJkagKjx3XaqyfRKXw== 621 | 622 | is-number@^7.0.0: 623 | version "7.0.0" 624 | resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" 625 | integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== 626 | 627 | is-typed-array@^1.1.10, is-typed-array@^1.1.3: 628 | version "1.1.10" 629 | resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.10.tgz#36a5b5cb4189b575d1a3e4b08536bfb485801e3f" 630 | integrity sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A== 631 | dependencies: 632 | available-typed-arrays "^1.0.5" 633 | call-bind "^1.0.2" 634 | for-each "^0.3.3" 635 | gopd "^1.0.1" 636 | has-tostringtag "^1.0.0" 637 | 638 | is-unicode-supported@^0.1.0: 639 | version "0.1.0" 640 | resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" 641 | integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== 642 | 643 | isomorphic-ws@^4.0.1: 644 | version "4.0.1" 645 | resolved "https://registry.yarnpkg.com/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz#55fd4cd6c5e6491e76dc125938dd863f5cd4f2dc" 646 | integrity sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w== 647 | 648 | jayson@^4.0.0: 649 | version "4.0.0" 650 | resolved "https://registry.yarnpkg.com/jayson/-/jayson-4.0.0.tgz#145a0ced46f900934c9b307e1332bcb0c7dbdb17" 651 | integrity sha512-v2RNpDCMu45fnLzSk47vx7I+QUaOsox6f5X0CUlabAFwxoP+8MfAY0NQRFwOEYXIxm8Ih5y6OaEa5KYiQMkyAA== 652 | dependencies: 653 | "@types/connect" "^3.4.33" 654 | "@types/node" "^12.12.54" 655 | "@types/ws" "^7.4.4" 656 | JSONStream "^1.3.5" 657 | commander "^2.20.3" 658 | delay "^5.0.0" 659 | es6-promisify "^5.0.0" 660 | eyes "^0.1.8" 661 | isomorphic-ws "^4.0.1" 662 | json-stringify-safe "^5.0.1" 663 | uuid "^8.3.2" 664 | ws "^7.4.5" 665 | 666 | js-levenshtein@^1.1.6: 667 | version "1.1.6" 668 | resolved "https://registry.yarnpkg.com/js-levenshtein/-/js-levenshtein-1.1.6.tgz#c6cee58eb3550372df8deb85fad5ce66ce01d59d" 669 | integrity sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g== 670 | 671 | json-stringify-safe@^5.0.1: 672 | version "5.0.1" 673 | resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" 674 | integrity sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA== 675 | 676 | jsonparse@^1.2.0: 677 | version "1.3.1" 678 | resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280" 679 | integrity sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg== 680 | 681 | lodash@^4.17.21: 682 | version "4.17.21" 683 | resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" 684 | integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== 685 | 686 | log-symbols@^4.1.0: 687 | version "4.1.0" 688 | resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" 689 | integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== 690 | dependencies: 691 | chalk "^4.1.0" 692 | is-unicode-supported "^0.1.0" 693 | 694 | mimic-fn@^2.1.0: 695 | version "2.1.0" 696 | resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" 697 | integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== 698 | 699 | ms@2.1.2: 700 | version "2.1.2" 701 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" 702 | integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== 703 | 704 | msw@^1.2.1: 705 | version "1.2.1" 706 | resolved "https://registry.yarnpkg.com/msw/-/msw-1.2.1.tgz#9dd347583eeba5e5c7f33b54be5600a899dc61bd" 707 | integrity sha512-bF7qWJQSmKn6bwGYVPXOxhexTCGD5oJSZg8yt8IBClxvo3Dx/1W0zqE1nX9BSWmzRsCKWfeGWcB/vpqV6aclpw== 708 | dependencies: 709 | "@mswjs/cookies" "^0.2.2" 710 | "@mswjs/interceptors" "^0.17.5" 711 | "@open-draft/until" "^1.0.3" 712 | "@types/cookie" "^0.4.1" 713 | "@types/js-levenshtein" "^1.1.1" 714 | chalk "4.1.1" 715 | chokidar "^3.4.2" 716 | cookie "^0.4.2" 717 | graphql "^15.0.0 || ^16.0.0" 718 | headers-polyfill "^3.1.2" 719 | inquirer "^8.2.0" 720 | is-node-process "^1.2.0" 721 | js-levenshtein "^1.1.6" 722 | node-fetch "^2.6.7" 723 | outvariant "^1.4.0" 724 | path-to-regexp "^6.2.0" 725 | strict-event-emitter "^0.4.3" 726 | type-fest "^2.19.0" 727 | yargs "^17.3.1" 728 | 729 | mute-stream@0.0.8: 730 | version "0.0.8" 731 | resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" 732 | integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== 733 | 734 | node-fetch@^2.6.7: 735 | version "2.6.9" 736 | resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.9.tgz#7c7f744b5cc6eb5fd404e0c7a9fec630a55657e6" 737 | integrity sha512-DJm/CJkZkRjKKj4Zi4BsKVZh3ValV5IR5s7LVZnW+6YMh0W1BfNA8XSs6DLMGYlId5F3KnA70uu2qepcR08Qqg== 738 | dependencies: 739 | whatwg-url "^5.0.0" 740 | 741 | node-gyp-build@^4.3.0: 742 | version "4.6.0" 743 | resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.6.0.tgz#0c52e4cbf54bbd28b709820ef7b6a3c2d6209055" 744 | integrity sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ== 745 | 746 | normalize-path@^3.0.0, normalize-path@~3.0.0: 747 | version "3.0.0" 748 | resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" 749 | integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== 750 | 751 | onetime@^5.1.0: 752 | version "5.1.2" 753 | resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" 754 | integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== 755 | dependencies: 756 | mimic-fn "^2.1.0" 757 | 758 | ora@^5.4.1: 759 | version "5.4.1" 760 | resolved "https://registry.yarnpkg.com/ora/-/ora-5.4.1.tgz#1b2678426af4ac4a509008e5e4ac9e9959db9e18" 761 | integrity sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ== 762 | dependencies: 763 | bl "^4.1.0" 764 | chalk "^4.1.0" 765 | cli-cursor "^3.1.0" 766 | cli-spinners "^2.5.0" 767 | is-interactive "^1.0.0" 768 | is-unicode-supported "^0.1.0" 769 | log-symbols "^4.1.0" 770 | strip-ansi "^6.0.0" 771 | wcwidth "^1.0.1" 772 | 773 | os-tmpdir@~1.0.2: 774 | version "1.0.2" 775 | resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" 776 | integrity sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g== 777 | 778 | outvariant@^1.2.1, outvariant@^1.4.0: 779 | version "1.4.0" 780 | resolved "https://registry.yarnpkg.com/outvariant/-/outvariant-1.4.0.tgz#e742e4bda77692da3eca698ef5bfac62d9fba06e" 781 | integrity sha512-AlWY719RF02ujitly7Kk/0QlV+pXGFDHrHf9O2OKqyqgBieaPOIeuSkL8sRK6j2WK+/ZAURq2kZsY0d8JapUiw== 782 | 783 | path-to-regexp@^6.2.0: 784 | version "6.2.1" 785 | resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-6.2.1.tgz#d54934d6798eb9e5ef14e7af7962c945906918e5" 786 | integrity sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw== 787 | 788 | picomatch@^2.0.4, picomatch@^2.2.1: 789 | version "2.3.1" 790 | resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" 791 | integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== 792 | 793 | readable-stream@^3.4.0: 794 | version "3.6.2" 795 | resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" 796 | integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== 797 | dependencies: 798 | inherits "^2.0.3" 799 | string_decoder "^1.1.1" 800 | util-deprecate "^1.0.1" 801 | 802 | readdirp@~3.6.0: 803 | version "3.6.0" 804 | resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" 805 | integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== 806 | dependencies: 807 | picomatch "^2.2.1" 808 | 809 | regenerator-runtime@^0.13.11: 810 | version "0.13.11" 811 | resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9" 812 | integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg== 813 | 814 | require-directory@^2.1.1: 815 | version "2.1.1" 816 | resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" 817 | integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== 818 | 819 | restore-cursor@^3.1.0: 820 | version "3.1.0" 821 | resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e" 822 | integrity sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA== 823 | dependencies: 824 | onetime "^5.1.0" 825 | signal-exit "^3.0.2" 826 | 827 | rpc-websockets@^7.5.1: 828 | version "7.5.1" 829 | resolved "https://registry.yarnpkg.com/rpc-websockets/-/rpc-websockets-7.5.1.tgz#e0a05d525a97e7efc31a0617f093a13a2e10c401" 830 | integrity sha512-kGFkeTsmd37pHPMaHIgN1LVKXMi0JD782v4Ds9ZKtLlwdTKjn+CxM9A9/gLT2LaOuEcEFGL98h1QWQtlOIdW0w== 831 | dependencies: 832 | "@babel/runtime" "^7.17.2" 833 | eventemitter3 "^4.0.7" 834 | uuid "^8.3.2" 835 | ws "^8.5.0" 836 | optionalDependencies: 837 | bufferutil "^4.0.1" 838 | utf-8-validate "^5.0.2" 839 | 840 | run-async@^2.4.0: 841 | version "2.4.1" 842 | resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.1.tgz#8440eccf99ea3e70bd409d49aab88e10c189a455" 843 | integrity sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ== 844 | 845 | rxjs@^7.5.5: 846 | version "7.8.0" 847 | resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.8.0.tgz#90a938862a82888ff4c7359811a595e14e1e09a4" 848 | integrity sha512-F2+gxDshqmIub1KdvZkaEfGDwLNpPvk9Fs6LD/MyQxNgMds/WH9OdDDXOmxUZpME+iSK3rQCctkL0DYyytUqMg== 849 | dependencies: 850 | tslib "^2.1.0" 851 | 852 | safe-buffer@~5.2.0: 853 | version "5.2.1" 854 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" 855 | integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== 856 | 857 | "safer-buffer@>= 2.1.2 < 3": 858 | version "2.1.2" 859 | resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" 860 | integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== 861 | 862 | set-cookie-parser@^2.4.6: 863 | version "2.6.0" 864 | resolved "https://registry.yarnpkg.com/set-cookie-parser/-/set-cookie-parser-2.6.0.tgz#131921e50f62ff1a66a461d7d62d7b21d5d15a51" 865 | integrity sha512-RVnVQxTXuerk653XfuliOxBP81Sf0+qfQE73LIYKcyMYHG94AuH0kgrQpRDuTZnSmjpysHmzxJXKNfa6PjFhyQ== 866 | 867 | signal-exit@^3.0.2: 868 | version "3.0.7" 869 | resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" 870 | integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== 871 | 872 | strict-event-emitter@^0.2.4: 873 | version "0.2.8" 874 | resolved "https://registry.yarnpkg.com/strict-event-emitter/-/strict-event-emitter-0.2.8.tgz#b4e768927c67273c14c13d20e19d5e6c934b47ca" 875 | integrity sha512-KDf/ujU8Zud3YaLtMCcTI4xkZlZVIYxTLr+XIULexP+77EEVWixeXroLUXQXiVtH4XH2W7jr/3PT1v3zBuvc3A== 876 | dependencies: 877 | events "^3.3.0" 878 | 879 | strict-event-emitter@^0.4.3: 880 | version "0.4.6" 881 | resolved "https://registry.yarnpkg.com/strict-event-emitter/-/strict-event-emitter-0.4.6.tgz#ff347c8162b3e931e3ff5f02cfce6772c3b07eb3" 882 | integrity sha512-12KWeb+wixJohmnwNFerbyiBrAlq5qJLwIt38etRtKtmmHyDSoGlIqFE9wx+4IwG0aDjI7GV8tc8ZccjWZZtTg== 883 | 884 | string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: 885 | version "4.2.3" 886 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" 887 | integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== 888 | dependencies: 889 | emoji-regex "^8.0.0" 890 | is-fullwidth-code-point "^3.0.0" 891 | strip-ansi "^6.0.1" 892 | 893 | string_decoder@^1.1.1: 894 | version "1.3.0" 895 | resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" 896 | integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== 897 | dependencies: 898 | safe-buffer "~5.2.0" 899 | 900 | strip-ansi@^6.0.0, strip-ansi@^6.0.1: 901 | version "6.0.1" 902 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" 903 | integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== 904 | dependencies: 905 | ansi-regex "^5.0.1" 906 | 907 | superstruct@^1.0.3: 908 | version "1.0.3" 909 | resolved "https://registry.yarnpkg.com/superstruct/-/superstruct-1.0.3.tgz#de626a5b49c6641ff4d37da3c7598e7a87697046" 910 | integrity sha512-8iTn3oSS8nRGn+C2pgXSKPI3jmpm6FExNazNpjvqS6ZUJQCej3PUXEKM8NjHBOs54ExM+LPW/FBRhymrdcCiSg== 911 | 912 | supports-color@^7.1.0: 913 | version "7.2.0" 914 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" 915 | integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== 916 | dependencies: 917 | has-flag "^4.0.0" 918 | 919 | "through@>=2.2.7 <3", through@^2.3.6: 920 | version "2.3.8" 921 | resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" 922 | integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg== 923 | 924 | tmp@^0.0.33: 925 | version "0.0.33" 926 | resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" 927 | integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== 928 | dependencies: 929 | os-tmpdir "~1.0.2" 930 | 931 | to-regex-range@^5.0.1: 932 | version "5.0.1" 933 | resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" 934 | integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== 935 | dependencies: 936 | is-number "^7.0.0" 937 | 938 | tr46@~0.0.3: 939 | version "0.0.3" 940 | resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" 941 | integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== 942 | 943 | tslib@^2.1.0: 944 | version "2.5.0" 945 | resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.5.0.tgz#42bfed86f5787aeb41d031866c8f402429e0fddf" 946 | integrity sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg== 947 | 948 | tweetnacl@^1.0.3: 949 | version "1.0.3" 950 | resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-1.0.3.tgz#ac0af71680458d8a6378d0d0d050ab1407d35596" 951 | integrity sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw== 952 | 953 | type-fest@^0.21.3: 954 | version "0.21.3" 955 | resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" 956 | integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== 957 | 958 | type-fest@^2.19.0: 959 | version "2.19.0" 960 | resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-2.19.0.tgz#88068015bb33036a598b952e55e9311a60fd3a9b" 961 | integrity sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA== 962 | 963 | utf-8-validate@^5.0.2: 964 | version "5.0.10" 965 | resolved "https://registry.yarnpkg.com/utf-8-validate/-/utf-8-validate-5.0.10.tgz#d7d10ea39318171ca982718b6b96a8d2442571a2" 966 | integrity sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ== 967 | dependencies: 968 | node-gyp-build "^4.3.0" 969 | 970 | util-deprecate@^1.0.1: 971 | version "1.0.2" 972 | resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" 973 | integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== 974 | 975 | util@^0.12.3: 976 | version "0.12.5" 977 | resolved "https://registry.yarnpkg.com/util/-/util-0.12.5.tgz#5f17a6059b73db61a875668781a1c2b136bd6fbc" 978 | integrity sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA== 979 | dependencies: 980 | inherits "^2.0.3" 981 | is-arguments "^1.0.4" 982 | is-generator-function "^1.0.7" 983 | is-typed-array "^1.1.3" 984 | which-typed-array "^1.1.2" 985 | 986 | uuid@^8.3.2: 987 | version "8.3.2" 988 | resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" 989 | integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== 990 | 991 | wcwidth@^1.0.1: 992 | version "1.0.1" 993 | resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8" 994 | integrity sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg== 995 | dependencies: 996 | defaults "^1.0.3" 997 | 998 | web-encoding@^1.1.5: 999 | version "1.1.5" 1000 | resolved "https://registry.yarnpkg.com/web-encoding/-/web-encoding-1.1.5.tgz#fc810cf7667364a6335c939913f5051d3e0c4864" 1001 | integrity sha512-HYLeVCdJ0+lBYV2FvNZmv3HJ2Nt0QYXqZojk3d9FJOLkwnuhzM9tmamh8d7HPM8QqjKH8DeHkFTx+CFlWpZZDA== 1002 | dependencies: 1003 | util "^0.12.3" 1004 | optionalDependencies: 1005 | "@zxing/text-encoding" "0.9.0" 1006 | 1007 | webidl-conversions@^3.0.0: 1008 | version "3.0.1" 1009 | resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" 1010 | integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== 1011 | 1012 | whatwg-url@^5.0.0: 1013 | version "5.0.0" 1014 | resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" 1015 | integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== 1016 | dependencies: 1017 | tr46 "~0.0.3" 1018 | webidl-conversions "^3.0.0" 1019 | 1020 | which-typed-array@^1.1.2: 1021 | version "1.1.9" 1022 | resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.9.tgz#307cf898025848cf995e795e8423c7f337efbde6" 1023 | integrity sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA== 1024 | dependencies: 1025 | available-typed-arrays "^1.0.5" 1026 | call-bind "^1.0.2" 1027 | for-each "^0.3.3" 1028 | gopd "^1.0.1" 1029 | has-tostringtag "^1.0.0" 1030 | is-typed-array "^1.1.10" 1031 | 1032 | wrap-ansi@^7.0.0: 1033 | version "7.0.0" 1034 | resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" 1035 | integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== 1036 | dependencies: 1037 | ansi-styles "^4.0.0" 1038 | string-width "^4.1.0" 1039 | strip-ansi "^6.0.0" 1040 | 1041 | ws@^7.4.5: 1042 | version "7.5.9" 1043 | resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.9.tgz#54fa7db29f4c7cec68b1ddd3a89de099942bb591" 1044 | integrity sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q== 1045 | 1046 | ws@^8.5.0: 1047 | version "8.13.0" 1048 | resolved "https://registry.yarnpkg.com/ws/-/ws-8.13.0.tgz#9a9fb92f93cf41512a0735c8f4dd09b8a1211cd0" 1049 | integrity sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA== 1050 | 1051 | y18n@^5.0.5: 1052 | version "5.0.8" 1053 | resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" 1054 | integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== 1055 | 1056 | yargs-parser@^21.1.1: 1057 | version "21.1.1" 1058 | resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" 1059 | integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== 1060 | 1061 | yargs@^17.3.1: 1062 | version "17.7.1" 1063 | resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.1.tgz#34a77645201d1a8fc5213ace787c220eabbd0967" 1064 | integrity sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw== 1065 | dependencies: 1066 | cliui "^8.0.1" 1067 | escalade "^3.1.1" 1068 | get-caller-file "^2.0.5" 1069 | require-directory "^2.1.1" 1070 | string-width "^4.2.3" 1071 | y18n "^5.0.5" 1072 | yargs-parser "^21.1.1" 1073 | --------------------------------------------------------------------------------