From 5029b5dee749ca8756f58970b05d89188b4bff38 Mon Sep 17 00:00:00 2001 From: Aaron Choo Date: Thu, 21 Mar 2024 15:56:02 +0800 Subject: [PATCH] feat: broadcast directly instead of via wallet (#47) This PR changes the behaviour of all wallets such that the `signAndBroadcastTx` method will always broadcast via the user specified RPC, rather than broadcasted via the wallet extension. Unfortunately, Station mobile app does not support signing a tx without broadcasting it. Closes #17 --- CHANGELOG.md | 7 + README.md | 2 +- examples/verify-signatures/package.json | 5 +- examples/verify-signatures/pnpm-lock.yaml | 526 ------------------ examples/verify-signatures/src/index.ts | 116 ++-- package.json | 2 +- src/wallet/utils/verify.ts | 9 +- src/wallet/wallets/keplr/KeplrExtension.ts | 11 +- .../wallets/keplr/KeplrWalletConnectV2.ts | 1 - .../wallets/station/StationController.ts | 68 ++- .../wallets/station/StationExtension.ts | 88 +-- .../wallets/station/StationWalletConnectV1.ts | 2 + src/wallet/wallets/station/types.ts | 28 + 13 files changed, 123 insertions(+), 742 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 155f29c7..97f33e6f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## `v0.0.62` + +### Improvements + +- Txs are now broadcasted directly via the user-specified RPC instead of via the wallet (closes ) +- Update Station extension to use Keplr's API interface + ## `v0.0.60` ### Features diff --git a/README.md b/README.md index 451df2ea..b70722cd 100644 --- a/README.md +++ b/README.md @@ -154,7 +154,7 @@ See the [`benchmarks`](./benchmarks) folder, where the JS bundle size of CosmES | Package | Minified | Gzipped | |---------------|----------|---------| -| CosmES | 540 KB | 146 KB | +| CosmES | 537 KB | 147 KB | | Cosmos Kit v1 | 6004 KB | 1392 KB | | Cosmos Kit v2 | 6273 KB | 1453 KB | diff --git a/examples/verify-signatures/package.json b/examples/verify-signatures/package.json index 15f435ef..d2fd693a 100644 --- a/examples/verify-signatures/package.json +++ b/examples/verify-signatures/package.json @@ -6,13 +6,10 @@ "start": "tsx src/index.ts" }, "dependencies": { - "@keplr-wallet/cosmos": "^0.11.63", - "cosmes": "link:../..", - "secp256k1": "^5.0.0" + "cosmes": "link:../.." }, "devDependencies": { "@types/node": "^20.2.0", - "@types/secp256k1": "^4.0.3", "tsx": "^3.12.7", "typescript": "^5.0.4" } diff --git a/examples/verify-signatures/pnpm-lock.yaml b/examples/verify-signatures/pnpm-lock.yaml index b1d71ed8..7f7f6212 100644 --- a/examples/verify-signatures/pnpm-lock.yaml +++ b/examples/verify-signatures/pnpm-lock.yaml @@ -5,23 +5,14 @@ settings: excludeLinksFromLockfile: false dependencies: - '@keplr-wallet/cosmos': - specifier: ^0.11.63 - version: 0.11.63 cosmes: specifier: link:../.. version: link:../.. - secp256k1: - specifier: ^5.0.0 - version: 5.0.0 devDependencies: '@types/node': specifier: ^20.2.0 version: 20.2.0 - '@types/secp256k1': - specifier: ^4.0.3 - version: 4.0.3 tsx: specifier: ^3.12.7 version: 3.12.7 @@ -250,332 +241,14 @@ packages: dev: true optional: true - /@ethersproject/address@5.7.0: - resolution: {integrity: sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA==} - dependencies: - '@ethersproject/bignumber': 5.7.0 - '@ethersproject/bytes': 5.7.0 - '@ethersproject/keccak256': 5.7.0 - '@ethersproject/logger': 5.7.0 - '@ethersproject/rlp': 5.7.0 - dev: false - - /@ethersproject/bignumber@5.7.0: - resolution: {integrity: sha512-n1CAdIHRWjSucQO3MC1zPSVgV/6dy/fjL9pMrPP9peL+QxEg9wOsVqwD4+818B6LUEtaXzVHQiuivzRoxPxUGw==} - dependencies: - '@ethersproject/bytes': 5.7.0 - '@ethersproject/logger': 5.7.0 - bn.js: 5.2.1 - dev: false - - /@ethersproject/bytes@5.7.0: - resolution: {integrity: sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A==} - dependencies: - '@ethersproject/logger': 5.7.0 - dev: false - - /@ethersproject/keccak256@5.7.0: - resolution: {integrity: sha512-2UcPboeL/iW+pSg6vZ6ydF8tCnv3Iu/8tUmLLzWWGzxWKFFqOBQFLo6uLUv6BDrLgCDfN28RJ/wtByx+jZ4KBg==} - dependencies: - '@ethersproject/bytes': 5.7.0 - js-sha3: 0.8.0 - dev: false - - /@ethersproject/logger@5.7.0: - resolution: {integrity: sha512-0odtFdXu/XHtjQXJYA3u9G0G8btm0ND5Cu8M7i5vhEcE8/HmF4Lbdqanwyv4uQTr2tx6b7fQRmgLrsnpQlmnig==} - dev: false - - /@ethersproject/rlp@5.7.0: - resolution: {integrity: sha512-rBxzX2vK8mVF7b0Tol44t5Tb8gomOHkj5guL+HhzQ1yBh/ydjGnpw6at+X6Iw0Kp3OzzzkcKp8N9r0W4kYSs9w==} - dependencies: - '@ethersproject/bytes': 5.7.0 - '@ethersproject/logger': 5.7.0 - dev: false - - /@keplr-wallet/common@0.11.63: - resolution: {integrity: sha512-2M0c4ivzqwmt8jz1tgZ61VmUIfb5c6nZevHnaUXLW+1/XlPFRr2irXNQVM81OJaz8kiK9Nw4eLmEUZP+S/EAfw==} - dependencies: - '@keplr-wallet/crypto': 0.11.63 - buffer: 6.0.3 - delay: 4.4.1 - dev: false - - /@keplr-wallet/cosmos@0.11.63: - resolution: {integrity: sha512-iOkPUVvYBYMRPRssU7m285hVV0QwYh6vXVqqGfDckkLI7UzvxlzwBI/gnGL+pZfATOlKsKzOm0xVFZqrf85qkw==} - dependencies: - '@ethersproject/address': 5.7.0 - '@keplr-wallet/common': 0.11.63 - '@keplr-wallet/crypto': 0.11.63 - '@keplr-wallet/proto-types': 0.11.63 - '@keplr-wallet/types': 0.11.63 - '@keplr-wallet/unit': 0.11.63 - axios: 0.27.2 - bech32: 1.1.4 - buffer: 6.0.3 - long: 4.0.0 - protobufjs: 6.11.3 - transitivePeerDependencies: - - debug - dev: false - - /@keplr-wallet/crypto@0.11.63: - resolution: {integrity: sha512-IyMcd+s9iRwqwNZ75mHfa1r3/bIVikmavxzccShOgFPDbV3kDI+I3ekDpR/3XS+B9bHIKwfWj8/rvqz4MXfFNg==} - dependencies: - '@ethersproject/keccak256': 5.7.0 - bip32: 2.0.6 - bip39: 3.1.0 - bs58check: 2.1.2 - buffer: 6.0.3 - crypto-js: 4.1.1 - elliptic: 6.5.4 - sha.js: 2.4.11 - dev: false - - /@keplr-wallet/proto-types@0.11.63: - resolution: {integrity: sha512-WRZMs5T52Fh6cZsf/77mWbrbUzjE/TEpvwGnzdy6Y5RawfrzyqDqfCcokjCpYuDFFeQ/tPVH/IMvpDPWJVqbJA==} - dependencies: - long: 4.0.0 - protobufjs: 6.11.3 - dev: false - - /@keplr-wallet/types@0.11.63: - resolution: {integrity: sha512-uzGrE6Dk9rzDyzM5IcOSJcyOePNZUEZSM3SkRTgK1mmJ2UkaVI2A6DTIT1/lpbS6GnYVnf/UophH0DzWL2wzoQ==} - dependencies: - axios: 0.27.2 - long: 4.0.0 - transitivePeerDependencies: - - debug - dev: false - - /@keplr-wallet/unit@0.11.63: - resolution: {integrity: sha512-mHEtu7+8ddGNMBvSbbvD/tQHT/Knl9w4KysDlkKdk5INMaYKxyZP+N+rRgj6la4JR0/UNB/KUFzCxygtUqofPw==} - dependencies: - '@keplr-wallet/types': 0.11.63 - big-integer: 1.6.51 - utility-types: 3.10.0 - transitivePeerDependencies: - - debug - dev: false - - /@noble/hashes@1.3.0: - resolution: {integrity: sha512-ilHEACi9DwqJB0pw7kv+Apvh50jiiSyR/cQ3y4W7lOR5mhvn/50FLUfsnfJz0BDZtl/RR16kXvptiv6q1msYZg==} - dev: false - - /@protobufjs/aspromise@1.1.2: - resolution: {integrity: sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==} - dev: false - - /@protobufjs/base64@1.1.2: - resolution: {integrity: sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==} - dev: false - - /@protobufjs/codegen@2.0.4: - resolution: {integrity: sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==} - dev: false - - /@protobufjs/eventemitter@1.1.0: - resolution: {integrity: sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==} - dev: false - - /@protobufjs/fetch@1.1.0: - resolution: {integrity: sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==} - dependencies: - '@protobufjs/aspromise': 1.1.2 - '@protobufjs/inquire': 1.1.0 - dev: false - - /@protobufjs/float@1.0.2: - resolution: {integrity: sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==} - dev: false - - /@protobufjs/inquire@1.1.0: - resolution: {integrity: sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==} - dev: false - - /@protobufjs/path@1.1.2: - resolution: {integrity: sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==} - dev: false - - /@protobufjs/pool@1.1.0: - resolution: {integrity: sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==} - dev: false - - /@protobufjs/utf8@1.1.0: - resolution: {integrity: sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==} - dev: false - - /@types/long@4.0.2: - resolution: {integrity: sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==} - dev: false - - /@types/node@10.12.18: - resolution: {integrity: sha512-fh+pAqt4xRzPfqA6eh3Z2y6fyZavRIumvjhaCL753+TVkGKGhpPeyrJG2JftD0T9q4GF00KjefsQ+PQNDdWQaQ==} - dev: false - /@types/node@20.2.0: resolution: {integrity: sha512-3iD2jaCCziTx04uudpJKwe39QxXgSUnpxXSvRQjRvHPxFQfmfP4NXIm/NURVeNlTCc+ru4WqjYGTmpXrW9uMlw==} - - /@types/secp256k1@4.0.3: - resolution: {integrity: sha512-Da66lEIFeIz9ltsdMZcpQvmrmmoqrfju8pm1BH8WbYjZSwUgCwXLb9C+9XYogwBITnbsSaMdVPb2ekf7TV+03w==} - dependencies: - '@types/node': 20.2.0 dev: true - /asynckit@0.4.0: - resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} - dev: false - - /axios@0.27.2: - resolution: {integrity: sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==} - dependencies: - follow-redirects: 1.15.2 - form-data: 4.0.0 - transitivePeerDependencies: - - debug - dev: false - - /base-x@3.0.9: - resolution: {integrity: sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==} - dependencies: - safe-buffer: 5.2.1 - dev: false - - /base64-js@1.5.1: - resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} - dev: false - - /bech32@1.1.4: - resolution: {integrity: sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==} - dev: false - - /big-integer@1.6.51: - resolution: {integrity: sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==} - engines: {node: '>=0.6'} - dev: false - - /bindings@1.5.0: - resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} - dependencies: - file-uri-to-path: 1.0.0 - dev: false - - /bip32@2.0.6: - resolution: {integrity: sha512-HpV5OMLLGTjSVblmrtYRfFFKuQB+GArM0+XP8HGWfJ5vxYBqo+DesvJwOdC2WJ3bCkZShGf0QIfoIpeomVzVdA==} - engines: {node: '>=6.0.0'} - dependencies: - '@types/node': 10.12.18 - bs58check: 2.1.2 - create-hash: 1.2.0 - create-hmac: 1.1.7 - tiny-secp256k1: 1.1.6 - typeforce: 1.18.0 - wif: 2.0.6 - dev: false - - /bip39@3.1.0: - resolution: {integrity: sha512-c9kiwdk45Do5GL0vJMe7tS95VjCii65mYAH7DfWl3uW8AVzXKQVUm64i3hzVybBDMp9r7j9iNxR85+ul8MdN/A==} - dependencies: - '@noble/hashes': 1.3.0 - dev: false - - /bn.js@4.12.0: - resolution: {integrity: sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==} - dev: false - - /bn.js@5.2.1: - resolution: {integrity: sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==} - dev: false - - /brorand@1.1.0: - resolution: {integrity: sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==} - dev: false - - /bs58@4.0.1: - resolution: {integrity: sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==} - dependencies: - base-x: 3.0.9 - dev: false - - /bs58check@2.1.2: - resolution: {integrity: sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==} - dependencies: - bs58: 4.0.1 - create-hash: 1.2.0 - safe-buffer: 5.2.1 - dev: false - /buffer-from@1.1.2: resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} dev: true - /buffer@6.0.3: - resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} - dependencies: - base64-js: 1.5.1 - ieee754: 1.2.1 - dev: false - - /cipher-base@1.0.4: - resolution: {integrity: sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==} - dependencies: - inherits: 2.0.4 - safe-buffer: 5.2.1 - dev: false - - /combined-stream@1.0.8: - resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} - engines: {node: '>= 0.8'} - dependencies: - delayed-stream: 1.0.0 - dev: false - - /create-hash@1.2.0: - resolution: {integrity: sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==} - dependencies: - cipher-base: 1.0.4 - inherits: 2.0.4 - md5.js: 1.3.5 - ripemd160: 2.0.2 - sha.js: 2.4.11 - dev: false - - /create-hmac@1.1.7: - resolution: {integrity: sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==} - dependencies: - cipher-base: 1.0.4 - create-hash: 1.2.0 - inherits: 2.0.4 - ripemd160: 2.0.2 - safe-buffer: 5.2.1 - sha.js: 2.4.11 - dev: false - - /crypto-js@4.1.1: - resolution: {integrity: sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw==} - dev: false - - /delay@4.4.1: - resolution: {integrity: sha512-aL3AhqtfhOlT/3ai6sWXeqwnw63ATNpnUiN4HL7x9q+My5QtHlO3OIkasmug9LKzpheLdmUKGRKnYXYAS7FQkQ==} - engines: {node: '>=6'} - dev: false - - /delayed-stream@1.0.0: - resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} - engines: {node: '>=0.4.0'} - dev: false - - /elliptic@6.5.4: - resolution: {integrity: sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==} - dependencies: - bn.js: 4.12.0 - brorand: 1.1.0 - hash.js: 1.1.7 - hmac-drbg: 1.0.1 - inherits: 2.0.4 - minimalistic-assert: 1.0.1 - minimalistic-crypto-utils: 1.0.1 - dev: false - /esbuild@0.17.19: resolution: {integrity: sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw==} engines: {node: '>=12'} @@ -606,29 +279,6 @@ packages: '@esbuild/win32-x64': 0.17.19 dev: true - /file-uri-to-path@1.0.0: - resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} - dev: false - - /follow-redirects@1.15.2: - resolution: {integrity: sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==} - engines: {node: '>=4.0'} - peerDependencies: - debug: '*' - peerDependenciesMeta: - debug: - optional: true - dev: false - - /form-data@4.0.0: - resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} - engines: {node: '>= 6'} - dependencies: - asynckit: 0.4.0 - combined-stream: 1.0.8 - mime-types: 2.1.35 - dev: false - /fsevents@2.3.2: resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} @@ -641,145 +291,6 @@ packages: resolution: {integrity: sha512-MjhiaIWCJ1sAU4pIQ5i5OfOuHHxVo1oYeNsWTON7jxYkod8pHocXeh+SSbmu5OZZZK73B6cbJ2XADzXehLyovQ==} dev: true - /hash-base@3.1.0: - resolution: {integrity: sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==} - engines: {node: '>=4'} - dependencies: - inherits: 2.0.4 - readable-stream: 3.6.2 - safe-buffer: 5.2.1 - dev: false - - /hash.js@1.1.7: - resolution: {integrity: sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==} - dependencies: - inherits: 2.0.4 - minimalistic-assert: 1.0.1 - dev: false - - /hmac-drbg@1.0.1: - resolution: {integrity: sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==} - dependencies: - hash.js: 1.1.7 - minimalistic-assert: 1.0.1 - minimalistic-crypto-utils: 1.0.1 - dev: false - - /ieee754@1.2.1: - resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} - dev: false - - /inherits@2.0.4: - resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} - dev: false - - /js-sha3@0.8.0: - resolution: {integrity: sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==} - dev: false - - /long@4.0.0: - resolution: {integrity: sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==} - dev: false - - /md5.js@1.3.5: - resolution: {integrity: sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==} - dependencies: - hash-base: 3.1.0 - inherits: 2.0.4 - safe-buffer: 5.2.1 - dev: false - - /mime-db@1.52.0: - resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} - engines: {node: '>= 0.6'} - dev: false - - /mime-types@2.1.35: - resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} - engines: {node: '>= 0.6'} - dependencies: - mime-db: 1.52.0 - dev: false - - /minimalistic-assert@1.0.1: - resolution: {integrity: sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==} - dev: false - - /minimalistic-crypto-utils@1.0.1: - resolution: {integrity: sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==} - dev: false - - /nan@2.17.0: - resolution: {integrity: sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ==} - dev: false - - /node-addon-api@5.1.0: - resolution: {integrity: sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==} - dev: false - - /node-gyp-build@4.6.0: - resolution: {integrity: sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ==} - hasBin: true - dev: false - - /protobufjs@6.11.3: - resolution: {integrity: sha512-xL96WDdCZYdU7Slin569tFX712BxsxslWwAfAhCYjQKGTq7dAU91Lomy6nLLhh/dyGhk/YH4TwTSRxTzhuHyZg==} - hasBin: true - requiresBuild: true - dependencies: - '@protobufjs/aspromise': 1.1.2 - '@protobufjs/base64': 1.1.2 - '@protobufjs/codegen': 2.0.4 - '@protobufjs/eventemitter': 1.1.0 - '@protobufjs/fetch': 1.1.0 - '@protobufjs/float': 1.0.2 - '@protobufjs/inquire': 1.1.0 - '@protobufjs/path': 1.1.2 - '@protobufjs/pool': 1.1.0 - '@protobufjs/utf8': 1.1.0 - '@types/long': 4.0.2 - '@types/node': 20.2.0 - long: 4.0.0 - dev: false - - /readable-stream@3.6.2: - resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} - engines: {node: '>= 6'} - dependencies: - inherits: 2.0.4 - string_decoder: 1.3.0 - util-deprecate: 1.0.2 - dev: false - - /ripemd160@2.0.2: - resolution: {integrity: sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==} - dependencies: - hash-base: 3.1.0 - inherits: 2.0.4 - dev: false - - /safe-buffer@5.2.1: - resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} - dev: false - - /secp256k1@5.0.0: - resolution: {integrity: sha512-TKWX8xvoGHrxVdqbYeZM9w+izTF4b9z3NhSaDkdn81btvuh+ivbIMGT/zQvDtTFWhRlThpoz6LEYTr7n8A5GcA==} - engines: {node: '>=14.0.0'} - requiresBuild: true - dependencies: - elliptic: 6.5.4 - node-addon-api: 5.1.0 - node-gyp-build: 4.6.0 - dev: false - - /sha.js@2.4.11: - resolution: {integrity: sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==} - hasBin: true - dependencies: - inherits: 2.0.4 - safe-buffer: 5.2.1 - dev: false - /source-map-support@0.5.21: resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} dependencies: @@ -792,24 +303,6 @@ packages: engines: {node: '>=0.10.0'} dev: true - /string_decoder@1.3.0: - resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} - dependencies: - safe-buffer: 5.2.1 - dev: false - - /tiny-secp256k1@1.1.6: - resolution: {integrity: sha512-FmqJZGduTyvsr2cF3375fqGHUovSwDi/QytexX1Se4BPuPZpTE5Ftp5fg+EFSuEf3lhZqgCRjEG3ydUQ/aNiwA==} - engines: {node: '>=6.0.0'} - requiresBuild: true - dependencies: - bindings: 1.5.0 - bn.js: 4.12.0 - create-hmac: 1.1.7 - elliptic: 6.5.4 - nan: 2.17.0 - dev: false - /tsx@3.12.7: resolution: {integrity: sha512-C2Ip+jPmqKd1GWVQDvz/Eyc6QJbGfE7NrR3fx5BpEHMZsEHoIxHL1j+lKdGobr8ovEyqeNkPLSKp6SCSOt7gmw==} hasBin: true @@ -821,27 +314,8 @@ packages: fsevents: 2.3.2 dev: true - /typeforce@1.18.0: - resolution: {integrity: sha512-7uc1O8h1M1g0rArakJdf0uLRSSgFcYexrVoKo+bzJd32gd4gDy2L/Z+8/FjPnU9ydY3pEnVPtr9FyscYY60K1g==} - dev: false - /typescript@5.0.4: resolution: {integrity: sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==} engines: {node: '>=12.20'} hasBin: true dev: true - - /util-deprecate@1.0.2: - resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} - dev: false - - /utility-types@3.10.0: - resolution: {integrity: sha512-O11mqxmi7wMKCo6HKFt5AhO4BwY3VV68YU07tgxfz8zJTIxr4BpsezN49Ffwy9j3ZpwwJp4fkRwjRzq3uWE6Rg==} - engines: {node: '>= 4'} - dev: false - - /wif@2.0.6: - resolution: {integrity: sha512-HIanZn1zmduSF+BQhkE+YXIbEiH0xPr1012QbFEGB0xsKqJii0/SqJjyn8dFv6y36kOznMgMB+LGcbZTJ1xACQ==} - dependencies: - bs58check: 2.1.2 - dev: false diff --git a/examples/verify-signatures/src/index.ts b/examples/verify-signatures/src/index.ts index 9b5640f2..bd3e5784 100644 --- a/examples/verify-signatures/src/index.ts +++ b/examples/verify-signatures/src/index.ts @@ -1,87 +1,39 @@ -import { verifyADR36Amino } from "@keplr-wallet/cosmos"; -import { recoverPubKeyFromEthSignature } from "cosmes/codec"; -import { createHash } from "node:crypto"; -import { ecdsaVerify } from "secp256k1"; +import { MnemonicWallet, verifyArbitrary } from "cosmes/wallet"; -/** - * Returns true iff the signature is valid for the given data and public key. - * Works for Keplr / Leap / Cosmostation. - */ -function verifyArbitraryKeplr( - prefix: string, - address: string, - data: string, - pubKey: string, - signature: string -) { - return verifyADR36Amino( - prefix, - address, - data, - Buffer.from(pubKey, "base64"), - Buffer.from(signature, "base64") - ); -} +async function main() { + // Create a mnemonic wallet to sign an arbitrary message + const wallet = new MnemonicWallet({ + // TODO: replace with your mnemonic + mnemonic: + "witness snack faint milk gesture memory exhibit oak require mountain hammer crawl innocent day library drum youth result mutual remove capable hour front connect", + bech32Prefix: "osmo", + chainId: "osmosis-1", + rpc: "https://rpc.osmosis.zone", + gasPrice: { + amount: "0.0025", + denom: "uosmo", + }, + }); -/** - * Returns true iff the signature is valid for the given data and public key. - * Works for Station (Extension & WalletConnect). - */ -function verifyArbitraryStation( - data: string, - pubKey: string, - signature: string -) { - return ecdsaVerify( - Buffer.from(signature, "base64"), - createHash("sha256").update(data).digest(), - Buffer.from(pubKey, "base64") - ); -} + // Sign the arbitrary data + const message = "Hello from CosmES!"; + const { signature, pubKey } = await wallet.signArbitrary(message); + + // Verify the signature of the arbitrary data + const isValidSignature = verifyArbitrary({ + wallet: wallet.id, + bech32Prefix: "osmo", + data: message, + pubKey, + signature, + type: "secp256k1", + }); -/** - * Returns true iff the signature is valid for the given data and public key. - * Works for Metamask. - */ -function verifyArbitraryMetamask( - data: string, - pubKey: string, - signature: string -) { - const recoveredPubKey = recoverPubKeyFromEthSignature( - Buffer.from(data, "utf8"), - Buffer.from(signature, "base64") - ); - return pubKey === Buffer.from(recoveredPubKey).toString("base64"); + console.log({ + pubKey, + signature, + isValidSignature, + }); } -console.log( - verifyArbitraryKeplr( - // TODO: fill in chain prefix (eg. "osmo") - "", - // TODO: fill in address (eg. "osmo1...") - "", - // TODO: change data if necessary - "Hi from CosmeES! This is a test message just to prove that the wallet is working.", - // TODO: fill in base64 pubKey - "", - // TODO: fill in base64 signature - "" - ), - verifyArbitraryStation( - // TODO: change data if necessary - "Hi from CosmeES! This is a test message just to prove that the wallet is working.", - // TODO: fill in base64 pubKey - "", - // TODO: fill in base64 signature - "" - ), - verifyArbitraryMetamask( - // TODO: change data if necessary - "Hi from CosmeES! This is a test message just to prove that the wallet is working.", - // TODO: fill in base64 pubKey - "", - // TODO: fill in base64 signature - "" - ) -); +main(); diff --git a/package.json b/package.json index 15e2b0f2..09ec5c8c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cosmes", - "version": "0.0.60", + "version": "0.0.62", "private": false, "packageManager": "pnpm@8.3.0", "sideEffects": false, diff --git a/src/wallet/utils/verify.ts b/src/wallet/utils/verify.ts index 991e7592..200a4f5c 100644 --- a/src/wallet/utils/verify.ts +++ b/src/wallet/utils/verify.ts @@ -43,7 +43,6 @@ export function verifyArbitrary({ type = "secp256k1", }: VerifyArbitraryParams): boolean { const params = { - wallet, pubKey: base64.decode(pubKey), bech32Prefix, data: utf8.decode(data), @@ -54,14 +53,10 @@ export function verifyArbitrary({ switch (wallet) { case WalletName.STATION: return verifyECDSA(params); - case WalletName.COMPASS: - case WalletName.COSMOSTATION: - case WalletName.KEPLR: - case WalletName.LEAP: - case WalletName.NINJI: - return verifyADR36(params); case WalletName.METAMASK_INJECTIVE: return verifyEIP191(params); + default: + return verifyADR36(params); } } catch (err) { return false; diff --git a/src/wallet/wallets/keplr/KeplrExtension.ts b/src/wallet/wallets/keplr/KeplrExtension.ts index cdf0d693..b0802855 100644 --- a/src/wallet/wallets/keplr/KeplrExtension.ts +++ b/src/wallet/wallets/keplr/KeplrExtension.ts @@ -1,17 +1,17 @@ import { PlainMessage } from "@bufbuild/protobuf"; import { + RpcClient, Secp256k1PubKey, ToSignDocParams, ToStdSignDocParams, Tx, } from "cosmes/client"; -import { base16 } from "cosmes/codec"; import { CosmosBaseV1beta1Coin as Coin, CosmosTxV1beta1Fee as Fee, CosmosTxV1beta1TxRaw as TxRaw, } from "cosmes/protobufs"; -import type { BroadcastMode, Keplr } from "cosmes/registry"; +import type { Keplr } from "cosmes/registry"; import { WalletName } from "../../constants/WalletName"; import { WalletType } from "../../constants/WalletType"; @@ -99,11 +99,6 @@ export class KeplrExtension extends ConnectedWallet { txRaw = tx.toSignedDirect(signed, signature.signature); } - const txHash = await this.ext.sendTx( - this.chainId, - txRaw.toBinary(), - "sync" as BroadcastMode - ); - return base16.encode(txHash); + return RpcClient.broadcastTx(this.rpc, txRaw); } } diff --git a/src/wallet/wallets/keplr/KeplrWalletConnectV2.ts b/src/wallet/wallets/keplr/KeplrWalletConnectV2.ts index d9538941..458ae69c 100644 --- a/src/wallet/wallets/keplr/KeplrWalletConnectV2.ts +++ b/src/wallet/wallets/keplr/KeplrWalletConnectV2.ts @@ -89,7 +89,6 @@ export class KeplrWalletConnectV2 extends ConnectedWallet { txRaw = tx.toSignedDirect(signed, signature.signature); } - // Since `sendTx` on WC isn't implemented yet, we have to broadcast manually return RpcClient.broadcastTx(this.rpc, txRaw); } } diff --git a/src/wallet/wallets/station/StationController.ts b/src/wallet/wallets/station/StationController.ts index c4a6ba9f..bd3a575a 100644 --- a/src/wallet/wallets/station/StationController.ts +++ b/src/wallet/wallets/station/StationController.ts @@ -1,5 +1,4 @@ import { Secp256k1PubKey, getAccount, toBaseAccount } from "cosmes/client"; -import { base64 } from "cosmes/codec"; import { CosmosCryptoSecp256k1PubKey } from "cosmes/protobufs"; import { WalletName } from "../../constants/WalletName"; @@ -14,7 +13,7 @@ import { StationWalletConnectV1 } from "./StationWalletConnectV1"; const TERRA_CLASSIC_MAINNET_CHAIN_ID = "columbus-5"; const TERRA_MAINNET_CHAIN_ID = "phoenix-1"; const TERRA_TESTNET_CHAIN_ID = "pisco-1"; -const TERRA_CHAINS = [ +const COIN_TYPE_330_CHAINS = [ TERRA_CLASSIC_MAINNET_CHAIN_ID, TERRA_MAINNET_CHAIN_ID, TERRA_TESTNET_CHAIN_ID, @@ -51,7 +50,7 @@ export class StationController extends WalletController { for (const { chainId } of chains) { // Station mobile's WallectConnect only supports these chains // TODO: update when Station mobile supports more chains - if (TERRA_CHAINS.includes(chainId)) { + if (COIN_TYPE_330_CHAINS.includes(chainId)) { continue; } throw new Error(`${chainId} not supported`); @@ -83,34 +82,46 @@ export class StationController extends WalletController { protected async connectExtension(chains: ChainInfo[]) { const wallets = new Map(); - const ext = window.station; + const ext = window.station?.keplr; if (!ext) { throw new Error("Station extension is not installed"); } - const { addresses, pubkey } = await ext.connect(); - // Station will only return one or the other, but not both - // so we simply set the other one manually - addresses[TERRA_CLASSIC_MAINNET_CHAIN_ID] ??= - addresses[TERRA_MAINNET_CHAIN_ID] ?? addresses[TERRA_TESTNET_CHAIN_ID]; - addresses[TERRA_MAINNET_CHAIN_ID] ??= - addresses[TERRA_CLASSIC_MAINNET_CHAIN_ID]; - for (const { chainId, rpc, gasPrice } of chains) { - const address = addresses[chainId]; - if (address == null) { - throw new Error(`${chainId} not supported`); - } - const coinType = TERRA_CHAINS.includes(chainId) ? "330" : "118"; - const key = pubkey - ? new Secp256k1PubKey({ + // This method never throws on Station + await ext.enable(chains.map(({ chainId }) => chainId)); + for (const { chainId, rpc, gasPrice } of Object.values(chains)) { + try { + const { bech32Address, pubKey, isNanoLedger } = await ext.getKey( + chainId + ); + const key = new Secp256k1PubKey({ + key: pubKey, + chainId, + }); + wallets.set( + chainId, + new StationExtension( + this.id, + ext, chainId, - key: base64.decode(pubkey[coinType]), - }) - : // Legacy support for older versions of Station that don't return pubkey - await this.getPubKey(chainId, rpc, address); - wallets.set( - chainId, - new StationExtension(ext, chainId, key, address, rpc, gasPrice) - ); + key, + bech32Address, + rpc, + gasPrice, + isNanoLedger + ) + ); + } catch (err) { + if ( + err instanceof Error && + err.message === "The requested chain is not available on Station." + ) { + // If the chain is not supported, we simply log and ignore it + err.message = `There is no chain info for ${chainId}`; // Change to Keplr's error message + console.warn(err); + continue; + } + throw err; // Rethrow unhandled errors + } } return wallets; } @@ -119,6 +130,9 @@ export class StationController extends WalletController { onWindowEvent("station_wallet_change", () => this.changeAccount(WalletType.EXTENSION) ); + onWindowEvent("station_network_change", () => + this.changeAccount(WalletType.EXTENSION) + ); // Station's WalletConnect v1 doesn't support account change events } diff --git a/src/wallet/wallets/station/StationExtension.ts b/src/wallet/wallets/station/StationExtension.ts index ee9df7a2..0462da47 100644 --- a/src/wallet/wallets/station/StationExtension.ts +++ b/src/wallet/wallets/station/StationExtension.ts @@ -1,86 +1,4 @@ -import { PlainMessage } from "@bufbuild/protobuf"; -import { Secp256k1PubKey } from "cosmes/client"; -import { base64, utf8 } from "cosmes/codec"; -import { - CosmosBaseV1beta1Coin as Coin, - CosmosTxV1beta1Fee as Fee, -} from "cosmes/protobufs"; +import { KeplrExtension } from "../keplr/KeplrExtension"; -import { WalletName } from "../../constants/WalletName"; -import { WalletType } from "../../constants/WalletType"; -import { - ConnectedWallet, - SignArbitraryResponse, - UnsignedTx, -} from "../ConnectedWallet"; -import { Station } from "./types"; -import { toStationTx } from "./utils/toStationTx"; - -export class StationExtension extends ConnectedWallet { - private readonly ext: Station; - - constructor( - ext: Station, - chainId: string, - pubKey: Secp256k1PubKey, - address: string, - rpc: string, - gasPrice: PlainMessage - ) { - super( - WalletName.STATION, - WalletType.EXTENSION, - chainId, - pubKey, - address, - rpc, - gasPrice - ); - this.ext = ext; - } - - public async signArbitrary(data: string): Promise { - const { public_key, signature } = await this.normaliseError( - this.ext.signBytes(base64.encode(utf8.decode(data)), true) - ); - return { - data, - pubKey: public_key, - signature: signature, - }; - } - - public async signAndBroadcastTx( - unsignedTx: UnsignedTx, - fee: Fee - ): Promise { - const { msgs, memo } = unsignedTx; - const { code, raw_log, txhash } = await this.normaliseError( - this.ext.post(toStationTx(this.chainId, fee, msgs, memo), true) - ); - if (code) { - throw new Error(raw_log); - } - return txhash; - } - - /** - * Normalises the error thrown by the Station extension into a standard `Error` - * instance. Returns the result of the `promise` if it resolves successfully. - */ - private async normaliseError(promise: Promise): Promise { - try { - return await promise; - } catch (err) { - if (typeof err === "string") { - throw new Error(err); - } - if (err instanceof Error) { - throw err; - } - throw new Error( - "Unknown error from Station extension: " + JSON.stringify(err) - ); - } - } -} +// Station's API is similar to Keplr. +export const StationExtension = KeplrExtension; diff --git a/src/wallet/wallets/station/StationWalletConnectV1.ts b/src/wallet/wallets/station/StationWalletConnectV1.ts index 87a2d9dd..9f759c9a 100644 --- a/src/wallet/wallets/station/StationWalletConnectV1.ts +++ b/src/wallet/wallets/station/StationWalletConnectV1.ts @@ -57,6 +57,8 @@ export class StationWalletConnectV1 extends ConnectedWallet { { msgs, memo }: UnsignedTx, fee: Fee ): Promise { + // Signing a tx without posting it isn't supported + // See: https://github.com/terra-money/wallet-kit/blob/79600bb096d64754160909871dfdf89944120ce8/src/%40terra-money/terra-station-mobile/index.ts#L304 const { txhash } = await this.sendRequest( "post", toStationTx(this.chainId, fee, msgs, memo) diff --git a/src/wallet/wallets/station/types.ts b/src/wallet/wallets/station/types.ts index d6d515c6..8dd0f749 100644 --- a/src/wallet/wallets/station/types.ts +++ b/src/wallet/wallets/station/types.ts @@ -1,3 +1,5 @@ +import { Keplr } from "cosmes/registry"; + export type Window = { station?: Station | undefined; }; @@ -8,10 +10,12 @@ export type Window = { * @see https://github.com/terra-money/wallet-kit/blob/79600bb096d64754160909871dfdf89944120ce8/src/%40terra-money/station-connector/index.ts#L66 */ export type Station = { + keplr?: Keplr | undefined; connect: () => Promise; getPublicKey: () => Promise; signBytes(bytes: string, purgeQueue?: boolean): Promise; post: (tx: StationTx, purgeQueue?: boolean) => Promise; + sign: (tx: StationTx, purgeQueue?: boolean) => Promise; }; export type StationTx = { @@ -29,6 +33,7 @@ export type ConnectResponse = { */ pubkey?: | { + "60": string; "118": string; "330": string; } @@ -60,3 +65,26 @@ export type PostResponse = { raw_log: string; txhash: string; }; + +// Unnecessary fields are omitted for brevity +export type SignResponse = { + auth_info: { + fee: { + amount: { + amount: string; + denom: string; + }[]; + gas_limit: string; + granter: string; + payer: string; + }; + signer_infos: { + mode_info: { + single: { + mode: string; + }; + }; + }[]; + }; + signatures: string[]; +};