diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index b0ef07b..5ed2acf 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -12,6 +12,11 @@ jobs: name: Formatting runs-on: ubuntu-latest steps: + - name: Setup Linux dependencies + if: runner.os == 'Linux' + run: | + sudo apt-get update + sudo apt install libudev-dev pkg-config - name: Checkout sources uses: actions/checkout@v2 - name: Run rustfmt @@ -24,6 +29,11 @@ jobs: name: Clippy runs-on: ubuntu-latest steps: + - name: Setup Linux dependencies + if: runner.os == 'Linux' + run: | + sudo apt-get update + sudo apt install libudev-dev pkg-config - name: Checkout sources uses: actions/checkout@v2 - name: Run clippy simple @@ -51,6 +61,11 @@ jobs: - build: Windows os: windows-latest steps: + - name: Setup Linux dependencies + if: runner.os == 'Linux' + run: | + sudo apt-get update + sudo apt install libudev-dev pkg-config - name: Checkout sources uses: actions/checkout@v2 - name: Run tests simple @@ -81,6 +96,11 @@ jobs: args: --path . script: scripts/simple-silo.sh steps: + - name: Setup Linux dependencies + if: runner.os == 'Linux' + run: | + sudo apt-get update + sudo apt install libudev-dev pkg-config - name: Checkout sources uses: actions/checkout@v2 - name: Install aurora-cli (Advanced CLI) diff --git a/Cargo.lock b/Cargo.lock index c46caa3..8bd25e5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -129,7 +129,7 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" dependencies = [ - "windows-sys 0.48.0", + "windows-sys", ] [[package]] @@ -139,7 +139,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "180abfa45703aebe0093f79badacc01b8fd4ea2e35118747e5811127f926e188" dependencies = [ "anstyle", - "windows-sys 0.48.0", + "windows-sys", ] [[package]] @@ -188,18 +188,18 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn 2.0.22", + "syn 2.0.23", ] [[package]] name = "async-trait" -version = "0.1.68" +version = "0.1.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9ccdd8f2a161be9bd5c023df56f1b2a0bd1d83872ae53b71a84a12c9bf6e842" +checksum = "7b2d0f03b3640e3a630367e40c468cb7f309529c708ed1d88597047b0e7c6ef7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.22", + "syn 2.0.23", ] [[package]] @@ -232,6 +232,7 @@ dependencies = [ "near-crypto", "near-jsonrpc-client", "near-jsonrpc-primitives", + "near-ledger", "near-primitives", "rand 0.8.5", "reqwest", @@ -239,6 +240,7 @@ dependencies = [ "serde", "serde_json", "shadow-rs", + "slip10", "thiserror", "tokio", ] @@ -369,7 +371,7 @@ version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0a4e37d16930f5459780f5621038b6382b9bb37c19016f39fb6b5808d831f174" dependencies = [ - "crypto-mac", + "crypto-mac 0.8.0", "digest 0.9.0", "opaque-debug", ] @@ -612,7 +614,7 @@ dependencies = [ "heck 0.4.1", "proc-macro2", "quote", - "syn 2.0.22", + "syn 2.0.23", ] [[package]] @@ -729,6 +731,16 @@ dependencies = [ "subtle", ] +[[package]] +name = "crypto-mac" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58bcd97a54c7ca5ce2f6eb16f6bede5b0ab5f0055fedc17d2f0b4466e21671ca" +dependencies = [ + "generic-array", + "subtle", +] + [[package]] name = "curve25519-dalek" version = "3.2.1" @@ -763,7 +775,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.22", + "syn 2.0.23", ] [[package]] @@ -774,7 +786,7 @@ checksum = "29a358ff9f12ec09c3e61fef9b5a9902623a695a46a917b07f269bff1445611a" dependencies = [ "darling_core", "quote", - "syn 2.0.22", + "syn 2.0.23", ] [[package]] @@ -785,7 +797,7 @@ checksum = "53e0efad4403bfc52dc201159c4b842a246a14b98c64b55dfd0f2d89729dfeb8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.22", + "syn 2.0.23", ] [[package]] @@ -820,6 +832,12 @@ dependencies = [ "crypto-common", ] +[[package]] +name = "doc-comment" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" + [[package]] name = "easy-ext" version = "0.2.9" @@ -866,22 +884,22 @@ dependencies = [ [[package]] name = "enum-map" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "988f0d17a0fa38291e5f41f71ea8d46a5d5497b9054d5a759fae2cbb819f2356" +checksum = "017b207acb4cc917f4c31758ed95c0bc63ddb0f358b22eb38f80a2b2a43f6b1f" dependencies = [ "enum-map-derive", ] [[package]] name = "enum-map-derive" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a4da76b3b6116d758c7ba93f7ec6a35d2e2cf24feda76c6e38a375f4d5c59f2" +checksum = "8560b409800a72d2d7860f8e5f4e0b0bd22bea6a352ea2a9ce30ccdef7f16d2f" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.23", ] [[package]] @@ -904,7 +922,7 @@ checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" dependencies = [ "errno-dragonfly", "libc", - "windows-sys 0.48.0", + "windows-sys", ] [[package]] @@ -1343,13 +1361,35 @@ dependencies = [ "serde", ] +[[package]] +name = "hidapi" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "798154e4b6570af74899d71155fb0072d5b17e6aa12f39c8ef22c60fb8ec99e7" +dependencies = [ + "cc", + "libc", + "pkg-config", + "winapi", +] + [[package]] name = "hmac" version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "126888268dcc288495a26bf004b38c5fdbb31682f992c84ceb046a1f0fe38840" dependencies = [ - "crypto-mac", + "crypto-mac 0.8.0", + "digest 0.9.0", +] + +[[package]] +name = "hmac" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "deae6d9dbb35ec2c502d62b8f7b1c000a0822c3b0794ba36b3149c0a1c840dff" +dependencies = [ + "crypto-mac 0.9.1", "digest 0.9.0", ] @@ -1361,7 +1401,7 @@ checksum = "17ea0a1394df5b6574da6e0c1ade9e78868c9fb0a4e5ef4428e32da4676b85b1" dependencies = [ "digest 0.9.0", "generic-array", - "hmac", + "hmac 0.8.1", ] [[package]] @@ -1573,7 +1613,7 @@ checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" dependencies = [ "hermit-abi 0.3.1", "libc", - "windows-sys 0.48.0", + "windows-sys", ] [[package]] @@ -1589,8 +1629,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24fddda5af7e54bf7da53067d6e802dbcc381d0a8eef629df528e3ebf68755cb" dependencies = [ "hermit-abi 0.3.1", - "rustix 0.38.1", - "windows-sys 0.48.0", + "rustix 0.38.2", + "windows-sys", ] [[package]] @@ -1610,9 +1650,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.6" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" +checksum = "62b02a5381cc465bd3041d84623d0fa3b66738b52b8e2fc3bab8ad63ab032f4a" [[package]] name = "jobserver" @@ -1656,6 +1696,43 @@ dependencies = [ "spin", ] +[[package]] +name = "ledger-apdu" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe435806c197dfeaa5efcded5e623c4b8230fd28fdf1e91e7a86e40ef2acbf90" +dependencies = [ + "arrayref", + "no-std-compat", + "snafu", +] + +[[package]] +name = "ledger-transport" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1117f2143d92c157197785bf57711d7b02f2cfa101e162f8ca7900fb7f976321" +dependencies = [ + "async-trait", + "ledger-apdu", +] + +[[package]] +name = "ledger-transport-hid" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45ba81a1f5f24396b37211478aff7fbcd605dd4544df8dbed07b9da3c2057aee" +dependencies = [ + "byteorder", + "cfg-if", + "hex", + "hidapi", + "ledger-transport", + "libc", + "log", + "thiserror", +] + [[package]] name = "libc" version = "0.2.147" @@ -1791,7 +1868,7 @@ checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" dependencies = [ "libc", "wasi 0.11.0+wasi-snapshot-preview1", - "windows-sys 0.48.0", + "windows-sys", ] [[package]] @@ -1933,6 +2010,19 @@ dependencies = [ "thiserror", ] +[[package]] +name = "near-ledger" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1edfdfadf4d772ea67c11d69cdbc8b8f0e0742d88c3baac64bdcf21482f7c950" +dependencies = [ + "ed25519-dalek", + "ledger-apdu", + "ledger-transport", + "ledger-transport-hid", + "slip10", +] + [[package]] name = "near-o11y" version = "0.17.0" @@ -2026,7 +2116,7 @@ checksum = "84c1eda300e2e78f4f945ae58117d49e806899f4a51ee2faa09eda5ebc2e6571" dependencies = [ "quote", "serde", - "syn 2.0.22", + "syn 2.0.23", ] [[package]] @@ -2038,7 +2128,7 @@ dependencies = [ "fs2", "near-rpc-error-core", "serde", - "syn 2.0.22", + "syn 2.0.23", ] [[package]] @@ -2061,6 +2151,12 @@ dependencies = [ "thiserror", ] +[[package]] +name = "no-std-compat" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b93853da6d84c2e3c7d730d6473e8817692dd89be387eb01b94d7f108ecb5b8c" + [[package]] name = "nu-ansi-term" version = "0.46.0" @@ -2225,7 +2321,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.22", + "syn 2.0.23", ] [[package]] @@ -2302,9 +2398,9 @@ checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" [[package]] name = "parity-scale-codec" -version = "3.6.2" +version = "3.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7467bc45fea3d77e829a4df331b9e969e2ec6a4dcd4e126e660f8509b40a475" +checksum = "756d439303e94fae44f288ba881ad29670c65b0c4b0e05674ca81061bb65f2c5" dependencies = [ "arrayvec", "bitvec", @@ -2316,9 +2412,9 @@ dependencies = [ [[package]] name = "parity-scale-codec-derive" -version = "3.6.2" +version = "3.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c9de611934c78014c455793552d0bf7d65a58211179c49996fde925aa667c38" +checksum = "9d884d78fcf214d70b1e239fcd1c6e5e95aa3be1881918da2e488cc946c7a476" dependencies = [ "proc-macro-crate 1.3.1", "proc-macro2", @@ -2367,29 +2463,29 @@ dependencies = [ [[package]] name = "pin-project" -version = "1.1.1" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e138fdd8263907a2b0e1b4e80b7e58c721126479b6e6eedfb1b402acea7b9bd" +checksum = "030ad2bc4db10a8944cb0d837f158bdfec4d4a4873ab701a95046770d11f8842" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.1" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1fef411b303e3e12d534fb6e7852de82da56edd937d895125821fb7c09436c7" +checksum = "ec2e072ecce94ec471b13398d5402c188e76ac03cf74dd1a975161b23a3f6d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.22", + "syn 2.0.23", ] [[package]] name = "pin-project-lite" -version = "0.2.9" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" +checksum = "4c40d25201921e5ff0c862a505c6557ea88568a4e3ace775ab55e93f2f4f9d57" [[package]] name = "pin-utils" @@ -2780,48 +2876,48 @@ dependencies = [ [[package]] name = "rustix" -version = "0.37.21" +version = "0.37.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62f25693a73057a1b4cb56179dd3c7ea21a7c6c5ee7d85781f5749b46f34b79c" +checksum = "8818fa822adcc98b18fedbb3632a6a33213c070556b5aa7c4c8cc21cff565c4c" dependencies = [ "bitflags 1.3.2", "errno", "io-lifetimes", "libc", "linux-raw-sys 0.3.8", - "windows-sys 0.48.0", + "windows-sys", ] [[package]] name = "rustix" -version = "0.38.1" +version = "0.38.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbc6396159432b5c8490d4e301d8c705f61860b8b6c863bf79942ce5401968f3" +checksum = "aabcb0461ebd01d6b79945797c27f8529082226cb630a9865a71870ff63532a4" dependencies = [ "bitflags 2.3.3", "errno", "libc", "linux-raw-sys 0.4.3", - "windows-sys 0.48.0", + "windows-sys", ] [[package]] name = "rustversion" -version = "1.0.12" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f3208ce4d8448b3f3e7d168a73f5e0c43a61e32930de3bceeccedb388b6bf06" +checksum = "dc31bd9b61a32c31f9650d18add92aa83a49ba979c143eefd27fe7177b05bd5f" [[package]] name = "ryu" -version = "1.0.13" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" +checksum = "fe232bdf6be8c8de797b22184ee71118d63780ea42ac85b61d1baa6d3b782ae9" [[package]] name = "scale-info" -version = "2.8.0" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad560913365790f17cbf12479491169f01b9d46d29cfc7422bf8c64bdc61b731" +checksum = "35c0a159d0c45c12b20c5a844feb1fe4bea86e28f17b92a5f0c42193634d3782" dependencies = [ "bitvec", "cfg-if", @@ -2832,9 +2928,9 @@ dependencies = [ [[package]] name = "scale-info-derive" -version = "2.8.0" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19df9bd9ace6cc2fe19387c96ce677e823e07d017ceed253e7bb3d1d1bd9c73b" +checksum = "912e55f6d20e0e80d63733872b40e1227c0bce1e1ab81ba67d696339bfd7fd29" dependencies = [ "proc-macro-crate 1.3.1", "proc-macro2", @@ -2844,11 +2940,11 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.21" +version = "0.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "713cfb06c7059f3588fb8044c0fad1d09e3c01d225e25b9220dbfdcf16dbb1b3" +checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" dependencies = [ - "windows-sys 0.42.0", + "windows-sys", ] [[package]] @@ -2907,22 +3003,22 @@ checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" [[package]] name = "serde" -version = "1.0.164" +version = "1.0.166" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e8c8cf938e98f769bc164923b06dce91cea1751522f46f8466461af04c9027d" +checksum = "d01b7404f9d441d3ad40e6a636a7782c377d2abdbe4fa2440e2edcc2f4f10db8" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.164" +version = "1.0.166" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9735b638ccc51c28bf6914d90a2e9725b377144fc612c49a611fddd1b631d68" +checksum = "5dd83d6dde2b6b2d466e14d9d1acce8816dedee94f735eac6395808b3483c6d6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.22", + "syn 2.0.23", ] [[package]] @@ -2938,13 +3034,13 @@ dependencies = [ [[package]] name = "serde_repr" -version = "0.1.12" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcec881020c684085e55a25f7fd888954d56609ef363479dc5a1305eb0d40cab" +checksum = "6f0a21fba416426ac927b1691996e82079f8b6156e920c85345f135b2e9ba2de" dependencies = [ "proc-macro2", "quote", - "syn 2.0.22", + "syn 2.0.23", ] [[package]] @@ -2984,7 +3080,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.22", + "syn 2.0.23", ] [[package]] @@ -3080,6 +3176,17 @@ dependencies = [ "autocfg", ] +[[package]] +name = "slip10" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28724a6e6f70b0cb115c580891483da6f3aa99e6a353598303a57f89d23aa6bc" +dependencies = [ + "ed25519-dalek", + "hmac 0.9.0", + "sha2 0.9.9", +] + [[package]] name = "smallvec" version = "1.10.0" @@ -3097,6 +3204,28 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "snafu" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb0656e7e3ffb70f6c39b3c2a86332bb74aa3c679da781642590f3c1118c5045" +dependencies = [ + "doc-comment", + "snafu-derive", +] + +[[package]] +name = "snafu-derive" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "475b3bbe5245c26f2d8a6f62d67c1f30eb9fffeccee721c45d162c3ebbdf81b2" +dependencies = [ + "heck 0.4.1", + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "socket2" version = "0.4.9" @@ -3166,9 +3295,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.22" +version = "2.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2efbeae7acf4eabd6bcdcbd11c92f45231ddda7539edc7806bd1a04a03b24616" +checksum = "59fb7d6d8281a51045d62b8eb3a7d1ce347b76f312af50cd3dc0af39c87c1737" dependencies = [ "proc-macro2", "quote", @@ -3191,8 +3320,8 @@ dependencies = [ "cfg-if", "fastrand", "redox_syscall", - "rustix 0.37.21", - "windows-sys 0.48.0", + "rustix 0.37.22", + "windows-sys", ] [[package]] @@ -3212,7 +3341,7 @@ checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.22", + "syn 2.0.23", ] [[package]] @@ -3305,7 +3434,7 @@ dependencies = [ "signal-hook-registry", "socket2", "tokio-macros", - "windows-sys 0.48.0", + "windows-sys", ] [[package]] @@ -3326,7 +3455,7 @@ checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.22", + "syn 2.0.23", ] [[package]] @@ -3511,7 +3640,7 @@ checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" dependencies = [ "proc-macro2", "quote", - "syn 2.0.22", + "syn 2.0.23", ] [[package]] @@ -3638,9 +3767,9 @@ checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" [[package]] name = "unicode-ident" -version = "1.0.9" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0" +checksum = "22049a19f4a68748a168c0fc439f9516686aa045927ff767eca0a85101fb6e73" [[package]] name = "unicode-normalization" @@ -3752,7 +3881,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.22", + "syn 2.0.23", "wasm-bindgen-shared", ] @@ -3786,7 +3915,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.22", + "syn 2.0.23", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -3849,21 +3978,6 @@ dependencies = [ "windows-targets", ] -[[package]] -name = "windows-sys" -version = "0.42.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" -dependencies = [ - "windows_aarch64_gnullvm 0.42.2", - "windows_aarch64_msvc 0.42.2", - "windows_i686_gnu 0.42.2", - "windows_i686_msvc 0.42.2", - "windows_x86_64_gnu 0.42.2", - "windows_x86_64_gnullvm 0.42.2", - "windows_x86_64_msvc 0.42.2", -] - [[package]] name = "windows-sys" version = "0.48.0" @@ -3879,93 +3993,51 @@ version = "0.48.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f" dependencies = [ - "windows_aarch64_gnullvm 0.48.0", - "windows_aarch64_msvc 0.48.0", - "windows_i686_gnu 0.48.0", - "windows_i686_msvc 0.48.0", - "windows_x86_64_gnu 0.48.0", - "windows_x86_64_gnullvm 0.48.0", - "windows_x86_64_msvc 0.48.0", + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", ] -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" - [[package]] name = "windows_aarch64_gnullvm" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" -[[package]] -name = "windows_aarch64_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" - [[package]] name = "windows_aarch64_msvc" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" -[[package]] -name = "windows_i686_gnu" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" - [[package]] name = "windows_i686_gnu" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" -[[package]] -name = "windows_i686_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" - [[package]] name = "windows_i686_msvc" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" -[[package]] -name = "windows_x86_64_gnu" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" - [[package]] name = "windows_x86_64_gnu" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" - [[package]] name = "windows_x86_64_gnullvm" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" -[[package]] -name = "windows_x86_64_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" - [[package]] name = "windows_x86_64_msvc" version = "0.48.0" @@ -4016,7 +4088,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.22", + "syn 2.0.23", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index b59552d..707672e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -44,6 +44,8 @@ serde_json = "1" shadow-rs = "0.23" thiserror = "1" tokio = { version = "1", features = ["full"] } +slip10 = "0.4.3" +near-ledger = "0.2" [dev-dependencies] rand = "0.8" diff --git a/scripts/simple-ledger.sh b/scripts/simple-ledger.sh new file mode 100755 index 0000000..cece66b --- /dev/null +++ b/scripts/simple-ledger.sh @@ -0,0 +1,112 @@ +#!/usr/bin/env bash + +export NEARCORE_HOME="/tmp/localnet" + +AURORA_PREV_VERSION="2.9.1" +AURORA_LAST_VERSION="2.9.1" +EVM_CODE=$(cat docs/res/HelloWorld.hex) +ABI_PATH="docs/res/HelloWorld.abi" +ENGINE_PREV_WASM_URL="https://github.com/aurora-is-near/aurora-engine/releases/download/$AURORA_PREV_VERSION/aurora-mainnet.wasm" +ENGINE_LAST_WASM_URL="https://github.com/aurora-is-near/aurora-engine/releases/download/$AURORA_LAST_VERSION/aurora-mainnet.wasm" +XCC_ROUTER_LAST_WASM_URL="https://github.com/aurora-is-near/aurora-engine/releases/download/$AURORA_LAST_VERSION/aurora-factory-mainnet.wasm" +ENGINE_WASM_PATH="/tmp/aurora-mainnet.wasm" +XCC_ROUTER_WASM_PATH="/tmp/aurora-factory-mainnet.wasm" +USER_BASE_BIN=$(python3 -m site --user-base)/bin +NODE_KEY_PATH=$NEARCORE_HOME/node0/validator_key.json +AURORA_KEY_PATH=$NEARCORE_HOME/node0/aurora_key.json +AURORA_SECRET_KEY=27cb3ddbd18037b38d7fb9ae3433a9d6f5cd554a4ba5768c8a15053f688ee167 +ENGINE_ACCOUNT=aurora.node0 + ## CHANGE ME FOR TESTNET +NEW_NAMED_ACCOUNT_FOR_LEDGER_TESTNET=xyz1123456781.testnet +NEW_NAMED_ACCOUNT_FOR_LEDGER_LOCALNET=xyz1123456781.node0 +## USE YOUR OWN LEDGER PUB KEY HERE +LEDGER_ACCOUNT_ID=3f6ab82e37adf3e6c91c9aa8f23ecfbb80d54e624ea56b0a619b0d94d6ee732c + +export PATH="$PATH:$USER_BASE_BIN:$HOME/.cargo/bin" + +# Install `nearup` utility if not installed before. +pip3 list | grep nearup > /dev/null || pip3 install --user nearup + +start_node() { + cmd="nearup run localnet --home $NEARCORE_HOME" + + if [[ $(uname -m) == "arm64" ]]; then # Check for local execution + cmd="$cmd --binary-path $HOME/.nearup/near/localnet" + fi + + $cmd > /dev/null 2>&1 +} + +stop_node() { + nearup stop > /dev/null 2>&1 +} + +finish() { + # Stop NEAR node. + stop_node + # Cleanup + rm -rf $NEARCORE_HOME + + if [[ -z "$1" ]]; then + exit 0 + else + exit "$1" + fi +} + +error_exit() { + finish 1 +} + +assert_eq() { + if [[ $1 != $2 ]]; then + echo "Unexpected result, should be $1 but actual is $2" + finish 1 + fi +} + +# Start NEAR node. +start_node +sleep 1 + +# Download Aurora EVM 2.8.1. +curl -sL $ENGINE_PREV_WASM_URL -o $ENGINE_WASM_PATH || error_exit + +export NEAR_KEY_PATH=$NODE_KEY_PATH + + +## TESTNET ONLY + +# Balance of Ledger account. +echo "View Ledger account: $LEDGER_ACCOUNT_ID (was already funded by another account)" +aurora-cli --network testnet view-account $LEDGER_ACCOUNT_ID || error_exit +sleep 1 + +# Create named account for the current ledger signe pub key. +echo "creating account $NEW_NAMED_ACCOUNT_FOR_LEDGER_TESTNET using ledger on testnet" +aurora-cli -u --network testnet create-account --account $NEW_NAMED_ACCOUNT_FOR_LEDGER_TESTNET --balance 1 +sleep 2 + +# Balance of Ledger account. +echo "View Ledger account: $NEW_NAMED_ACCOUNT_FOR_LEDGER_TESTNET on testnet" +aurora-cli --network testnet view-account $NEW_NAMED_ACCOUNT_FOR_LEDGER_TESTNET || error_exit +sleep 2 + +## LOCALNET ONLY + +# Create an account for Aurora EVM. +aurora-cli create-account --account $ENGINE_ACCOUNT --balance 100 > $AURORA_KEY_PATH || error_exit +sleep 1 + +# Fund the ledger account +echo "sending money to ledger account: $LEDGER_ACCOUNT_ID on localnet" +aurora-cli send-money --to $LEDGER_ACCOUNT_ID --amount 500 +sleep 1 + +# Balance of Ledger account. +echo "View Ledger account: $LEDGER_ACCOUNT_ID on localnet" +aurora-cli view-account $LEDGER_ACCOUNT_ID || error_exit +sleep 2 + +# Stop NEAR node and clean up. +finish diff --git a/src/cli/advanced/mod.rs b/src/cli/advanced/mod.rs index 9e150b1..ad615e4 100644 --- a/src/cli/advanced/mod.rs +++ b/src/cli/advanced/mod.rs @@ -68,6 +68,7 @@ pub async fn run(args: Cli) -> anyhow::Result<()> { near_endpoint, &config.engine_account_id, config.near_key_path.clone(), + false, ); near::execute_command(subcommand, &client, &config, config_path).await?; } diff --git a/src/cli/simple/command/mod.rs b/src/cli/simple/command/mod.rs index 7ee9689..d5a70df 100644 --- a/src/cli/simple/command/mod.rs +++ b/src/cli/simple/command/mod.rs @@ -402,6 +402,15 @@ pub async fn set_owner(client: Client, account_id: String) -> anyhow::Result<()> .await } +/// Fund Near account +pub async fn send_money(client: Client, account: String, amount: f64) -> anyhow::Result<()> { + match client.near().send_money(&account, amount).await { + Ok(result) => println!("{result}"), + Err(e) => eprintln!("{e:?}"), + } + Ok(()) +} + /// Register relayer address. pub async fn register_relayer(client: Client, address: String) -> anyhow::Result<()> { let args = hex_to_vec(&address)?; diff --git a/src/cli/simple/mod.rs b/src/cli/simple/mod.rs index 8e575ef..7d86a1d 100644 --- a/src/cli/simple/mod.rs +++ b/src/cli/simple/mod.rs @@ -1,4 +1,4 @@ -use clap::{Parser, Subcommand}; +use clap::{ArgAction, Parser, Subcommand}; use lazy_static::lazy_static; use shadow_rs::shadow; use std::str::FromStr; @@ -30,6 +30,9 @@ pub struct Cli { /// Path to file with NEAR account id and secret key in JSON format #[arg(long)] pub near_key_path: Option, + /// Uses ledger for creating new accounts/signing transactions + #[arg(long, short, action=ArgAction::SetTrue)] + pub use_ledger: bool, #[clap(subcommand)] pub command: Command, } @@ -103,6 +106,13 @@ pub enum Command { #[arg(short, long)] key: String, }, + /// Fund Near account + SendMoney { + #[arg(short, long)] + to: String, + #[arg(short, long)] + amount: f64, + }, /// Register relayer address RegisterRelayer { address: String }, /// Pause precompiles @@ -262,12 +272,15 @@ pub async fn run(args: Cli) -> anyhow::Result<()> { Network::Testnet => super::NEAR_TESTNET_ENDPOINT, Network::Localnet => super::NEAR_LOCAL_ENDPOINT, }; - let client = crate::client::Client::new(near_rpc, &args.engine, args.near_key_path); + // check use_ledger ? use ledger path : near_key_path. + let client = + crate::client::Client::new(near_rpc, &args.engine, args.near_key_path, args.use_ledger); match args.command { Command::GetChainId => command::get_chain_id(client).await?, Command::GetVersion => command::get_version(client).await?, Command::GetOwner => command::get_owner(client).await?, + Command::SendMoney { to, amount } => command::send_money(client, to, amount).await?, Command::SetOwner { account_id } => command::set_owner(client, account_id).await?, Command::RegisterRelayer { address } => command::register_relayer(client, address).await?, Command::GetBridgeProver => command::get_bridge_prover(client).await?, diff --git a/src/client/aurora.rs b/src/client/aurora.rs index 1c257eb..9c6bd36 100644 --- a/src/client/aurora.rs +++ b/src/client/aurora.rs @@ -206,7 +206,7 @@ impl AuroraClient { let near_rx_hex = near_tx_str.strip_prefix("0x").unwrap_or(near_tx_str); let near_receipt_id = hex::decode(near_rx_hex)?; let near_client = - super::NearClient::new(&self.near_url, self.engine_account_id.as_ref(), None); + super::NearClient::new(&self.near_url, self.engine_account_id.as_ref(), None, false); near_client .get_receipt_outcome(near_receipt_id.as_slice().try_into().unwrap()) diff --git a/src/client/mod.rs b/src/client/mod.rs index 5524e79..b4f5f99 100644 --- a/src/client/mod.rs +++ b/src/client/mod.rs @@ -30,15 +30,22 @@ pub struct Client { aurora_rpc: String, engine_account_id: AccountId, signer_key_path: Option, + use_ledger: bool, } #[cfg(feature = "simple")] impl Client { - pub fn new(near_rpc: &str, engine_account: &str, signer_key_path: Option) -> Self { + pub fn new( + near_rpc: &str, + engine_account: &str, + signer_key_path: Option, + ledger: bool, + ) -> Self { Self { near_rpc: near_rpc.to_string(), engine_account_id: engine_account.parse().expect("wrong engine account format"), signer_key_path, + use_ledger: ledger, } } @@ -47,6 +54,7 @@ impl Client { &self.near_rpc, self.engine_account_id.as_ref(), self.signer_key_path.clone(), + self.use_ledger, ) } } diff --git a/src/client/near.rs b/src/client/near.rs index fc726df..cc8f018 100644 --- a/src/client/near.rs +++ b/src/client/near.rs @@ -11,13 +11,20 @@ use near_jsonrpc_client::{ methods::broadcast_tx_commit::RpcBroadcastTxCommitRequest, AsUrl, JsonRpcClient, }; use near_jsonrpc_primitives::types::query::QueryResponseKind; -use near_primitives::transaction::Action; #[cfg(feature = "simple")] -use near_primitives::views::FinalExecutionStatus; use near_primitives::{ - hash::CryptoHash, transaction::SignedTransaction, types::AccountId, views, + account::{AccessKey, AccessKeyPermission}, + transaction::{AddKeyAction, CreateAccountAction, FunctionCallAction, TransferAction}, + views::FinalExecutionStatus, +}; +use near_primitives::{ + hash::CryptoHash, + transaction::{Action, DeployContractAction, Transaction}, + types::AccountId, + views, views::FinalExecutionOutcomeView, }; + #[cfg(feature = "simple")] use std::str::FromStr; @@ -32,15 +39,22 @@ pub struct NearClient { client: JsonRpcClient, pub engine_account_id: AccountId, signer_key_path: Option, + ledger: bool, } impl NearClient { - pub fn new(url: U, engine_account_id: &str, signer_key_path: Option) -> Self { + pub fn new( + url: U, + engine_account_id: &str, + signer_key_path: Option, + use_ledger: bool, + ) -> Self { let client = JsonRpcClient::connect(url); Self { client, engine_account_id: engine_account_id.parse().unwrap(), signer_key_path, + ledger: use_ledger, } } @@ -245,22 +259,75 @@ impl NearClient { let signer = self.signer()?; let (block_hash, nonce) = self.get_nonce(&signer).await?; let nonce = nonce_override.unwrap_or(nonce); + let unsigned_transaction = Transaction { + signer_id: signer.account_id.clone(), + public_key: signer.public_key.clone(), + nonce, + receiver_id: self.engine_account_id.parse().unwrap(), + block_hash, + actions, + }; - let request = RpcBroadcastTxCommitRequest { - signed_transaction: SignedTransaction::from_actions( - nonce, - signer.account_id.clone(), - self.engine_account_id.parse().unwrap(), - &signer, - actions, - block_hash, - ), + let signed_transaction = if self.ledger { + utils::sign_near_transaction_with_ledger(unsigned_transaction).unwrap() + } else { + unsigned_transaction.sign(&signer) }; - let response = self.client.call(request).await?; + + let request = RpcBroadcastTxCommitRequest { signed_transaction }; + + let response: FinalExecutionOutcomeView = self.client.call(request).await?; Ok(response) } + /// Fund NEAR account + #[cfg(feature = "simple")] + pub async fn send_money(&self, account: &str, amount: f64) -> anyhow::Result { + let signer = self.signer()?; + let receiver_id = AccountId::from_str(account)?; + let (block_hash, nonce) = self.get_nonce(&signer).await?; + let deposit = utils::near_to_yocto(amount); + + let unsigned_transaction = Transaction { + signer_id: signer.account_id.clone(), + public_key: signer.public_key.clone(), + nonce, + receiver_id: receiver_id.clone(), + block_hash, + actions: vec![Action::Transfer(TransferAction { deposit })], + }; + + let signed_transaction = if self.ledger { + utils::sign_near_transaction_with_ledger(unsigned_transaction).unwrap() + } else { + unsigned_transaction.sign(&signer) + }; + + let request = RpcBroadcastTxCommitRequest { signed_transaction }; + let response: FinalExecutionOutcomeView = self.client.call(request).await?; + + match &response.status { + FinalExecutionStatus::NotStarted => { + anyhow::bail!("Transaction execution status: not started") + } + FinalExecutionStatus::Started => anyhow::bail!("Transaction execution status: started"), + FinalExecutionStatus::Failure(error) => anyhow::bail!(error.to_string()), + FinalExecutionStatus::SuccessValue(result) => { + if String::from_utf8_lossy(result) == "false" { + anyhow::bail!( + "Error while creating account, tx hash: {}", + response.transaction.hash + ) + } + + Ok(format!( + "Account {receiver_id:?} has received {amount:?}NEAR" + )) + } + } + } + /// Creates new NEAR account. #[cfg(feature = "simple")] pub async fn create_account(&self, account: &str, deposit: f64) -> anyhow::Result { @@ -272,37 +339,67 @@ impl NearClient { let initial_balance = utils::near_to_yocto(deposit); let request = if is_sub_account { - RpcBroadcastTxCommitRequest { - signed_transaction: SignedTransaction::create_account( - nonce, - signer.account_id.clone(), - new_account_id, - initial_balance, - new_key_pair.public_key(), - &signer, - block_hash, - ), - } + let unsigned_transaction = Transaction { + signer_id: signer.account_id.clone(), + public_key: signer.public_key.clone(), + nonce, + receiver_id: new_account_id.clone(), + block_hash, + actions: vec![ + Action::CreateAccount(CreateAccountAction {}), + Action::AddKey(AddKeyAction { + public_key: new_key_pair.public_key(), + access_key: AccessKey { + nonce: 0, + permission: AccessKeyPermission::FullAccess, + }, + }), + Action::Transfer(TransferAction { + deposit: initial_balance, + }), + ], + }; + + let signed_transaction = if self.ledger { + utils::sign_near_transaction_with_ledger(unsigned_transaction).unwrap() + } else { + unsigned_transaction.sign(&signer) + }; + + RpcBroadcastTxCommitRequest { signed_transaction } } else { let contract_id = self.contract_id()?; - RpcBroadcastTxCommitRequest { - signed_transaction: SignedTransaction::call( - nonce, - signer.account_id.clone(), - contract_id, - &signer, - initial_balance, - "create_account".to_string(), - serde_json::json!({ + let new_public_key = if self.ledger { + signer.public_key.clone() // use the ledger public key for named account + } else { + new_key_pair.public_key() + }; + + let unsigned_transaction = Transaction { + signer_id: signer.account_id.clone(), + public_key: signer.public_key.clone(), + nonce, + receiver_id: contract_id, + block_hash, + actions: vec![Action::FunctionCall(FunctionCallAction { + args: serde_json::json!({ "new_account_id": new_account_id, - "new_public_key": new_key_pair.public_key(), + "new_public_key": new_public_key, }) .to_string() .into_bytes(), - NEAR_GAS, - block_hash, - ), - } + method_name: "create_account".to_string(), + gas: NEAR_GAS, + deposit: initial_balance, + })], + }; + let signed_transaction = if self.ledger { + utils::sign_near_transaction_with_ledger(unsigned_transaction).unwrap() + } else { + unsigned_transaction.sign(&signer) + }; + + RpcBroadcastTxCommitRequest { signed_transaction } }; let response = self.client.call(request).await?; @@ -337,19 +434,22 @@ impl NearClient { ) -> anyhow::Result { let signer = self.signer()?; let (block_hash, nonce) = self.get_nonce(&signer).await?; - let request = RpcBroadcastTxCommitRequest { - signed_transaction: SignedTransaction::from_actions( - nonce, - signer.account_id.clone(), - signer.account_id.clone(), - &signer, - vec![Action::DeployContract( - near_primitives::transaction::DeployContractAction { code }, - )], - block_hash, - ), + let unsigned_transaction = Transaction { + signer_id: signer.account_id.clone(), + public_key: signer.public_key.clone(), + nonce, + receiver_id: signer.account_id.clone(), + block_hash, + actions: vec![Action::DeployContract(DeployContractAction { code })], }; + let signed_transaction = if self.ledger { + utils::sign_near_transaction_with_ledger(unsigned_transaction).unwrap() + } else { + unsigned_transaction.sign(&signer) + }; + + let request = RpcBroadcastTxCommitRequest { signed_transaction }; self.client.call(request).await.map_err(Into::into) } @@ -400,7 +500,7 @@ impl NearClient { }; let response = self.client.call(request).await?; let block_hash = response.block_hash; - let nonce = match response.kind { + let nonce: u64 = match response.kind { QueryResponseKind::AccessKey(k) => k.nonce + 1, _ => anyhow::bail!("Wrong response kind: {:?}", response.kind), }; @@ -409,15 +509,22 @@ impl NearClient { } fn signer(&self) -> anyhow::Result { - std::env::var("NEAR_KEY_PATH") - .ok() - .as_ref() - .or(self.signer_key_path.as_ref()) - .map(std::path::Path::new) - .ok_or_else(|| { - anyhow::anyhow!("Path to the key file must be provided to use this functionality") - }) - .and_then(utils::read_key_file) + if self.ledger { + // use ledger singer! + utils::read_ledger_keypair() + } else { + std::env::var("NEAR_KEY_PATH") + .ok() + .as_ref() + .or(self.signer_key_path.as_ref()) + .map(std::path::Path::new) + .ok_or_else(|| { + anyhow::anyhow!( + "Path to the key file must be provided to use this functionality" + ) + }) + .and_then(utils::read_key_file) + } } #[cfg(feature = "simple")] diff --git a/src/utils/mod.rs b/src/utils/mod.rs index 2254f1d..00b7114 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -1,10 +1,13 @@ use aurora_engine_transactions::legacy::{LegacyEthSignedTransaction, TransactionLegacy}; use aurora_engine_types::{types::Address, U256}; use libsecp256k1::{Message, PublicKey, SecretKey}; -use near_crypto::InMemorySigner; +use near_crypto::{InMemorySigner, KeyType}; +use near_primitives::borsh::BorshSerialize; +use near_primitives::transaction::{SignedTransaction, Transaction}; use rlp::RlpStream; use serde::{Deserialize, Serialize}; -use std::path::Path; +use slip10::BIP32Path; +use std::{path::Path, str::FromStr}; pub mod abi; pub mod ft_metadata; @@ -74,6 +77,51 @@ pub fn read_key_file>(path: P) -> anyhow::Result } } +pub fn read_ledger_keypair() -> anyhow::Result { + //TODO: use prompt to get the HD derivation path from the user. + let input_seed_phrase_path = BIP32Path::from_str("44'/397'/0'/0'/1'").unwrap(); + let public_key = near_ledger::get_public_key(input_seed_phrase_path) + .map_err(|near_ledger_error| { + println!( + "An error occurred while trying to get PublicKey from Ledger device: {near_ledger_error:?}" + ); + }) + .unwrap(); + let near_public_key = + near_crypto::PublicKey::ED25519(near_crypto::ED25519PublicKey::from(public_key.to_bytes())); + let implicit_account_id = near_primitives::types::AccountId::try_from(hex::encode(public_key))?; + Ok(InMemorySigner { + account_id: implicit_account_id, + public_key: near_public_key, + // generate random seed to fulfill the return value. + // this secret key won't be used for signing the key. + secret_key: near_crypto::SecretKey::from_random(KeyType::ED25519), + }) +} + +pub fn sign_near_transaction_with_ledger( + unsiged_transaction: Transaction, +) -> anyhow::Result { + let input_seed_phrase_path = BIP32Path::from_str("44'/397'/0'/0'/1'").unwrap(); + match near_ledger::sign_transaction( + unsiged_transaction + .try_to_vec() + .expect("Transaction is not expected to fail on serialization"), + input_seed_phrase_path, + ) { + Ok(signature) => Ok(near_primitives::transaction::SignedTransaction::new( + near_crypto::Signature::from_parts(near_crypto::KeyType::ED25519, &signature) + .expect("Signature is not expected to fail on deserialization"), + unsiged_transaction, + )), + Err(error) => { + let message = format!("Error occurred while signing the transaction: {error:?}"); + let err = anyhow::Error::msg(message); + Err(err) + } + } +} + pub fn hex_to_vec(hex: &str) -> anyhow::Result> { hex::decode(hex.trim_start_matches("0x")) .map_err(|e| anyhow::anyhow!("Couldn't create vector from the hex: {hex}, {e}"))