Add gsio-client and gsio-wallet crates with initial implementations

- Introduced `gsio-client` crate for interacting with GSIO nodes, including ledger entry management and node discovery.
- Introduced `gsio-wallet` crate for key management, transaction creation, and wallet functionality.
- Updated workspace configuration to include new crates.
This commit is contained in:
geoffsee
2025-06-15 13:34:12 -04:00
parent 2f2ddc7f6d
commit 4c0848e2f3
10 changed files with 1146 additions and 49 deletions

4
.gitignore vendored
View File

@@ -2,3 +2,7 @@ target/
node_modules/
.wrangler/
.idea/
project/
/prompt.md
/todo
/.toak-ignore

567
Cargo.lock generated
View File

@@ -241,9 +241,9 @@ dependencies = [
"form_urlencoded",
"futures-util",
"http 1.3.1",
"http-body",
"http-body 1.0.1",
"http-body-util",
"hyper",
"hyper 1.6.0",
"hyper-util",
"itoa",
"matchit 0.8.4",
@@ -256,7 +256,7 @@ dependencies = [
"serde_json",
"serde_path_to_error",
"serde_urlencoded",
"sync_wrapper",
"sync_wrapper 1.0.2",
"tokio",
"tower",
"tower-layer",
@@ -273,12 +273,12 @@ dependencies = [
"bytes",
"futures-core",
"http 1.3.1",
"http-body",
"http-body 1.0.1",
"http-body-util",
"mime",
"pin-project-lite",
"rustversion",
"sync_wrapper",
"sync_wrapper 1.0.2",
"tower-layer",
"tower-service",
"tracing",
@@ -305,6 +305,12 @@ version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4cbbc9d0964165b47557570cce6c952866c2678457aca742aafc9fb771d30270"
[[package]]
name = "base64"
version = "0.21.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567"
[[package]]
name = "base64"
version = "0.22.1"
@@ -341,7 +347,16 @@ version = "0.10.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe"
dependencies = [
"digest",
"digest 0.10.7",
]
[[package]]
name = "block-buffer"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4"
dependencies = [
"generic-array",
]
[[package]]
@@ -557,6 +572,19 @@ dependencies = [
"cipher",
]
[[package]]
name = "curve25519-dalek"
version = "3.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61"
dependencies = [
"byteorder",
"digest 0.9.0",
"rand_core 0.5.1",
"subtle",
"zeroize",
]
[[package]]
name = "curve25519-dalek"
version = "4.1.3"
@@ -566,7 +594,7 @@ dependencies = [
"cfg-if",
"cpufeatures",
"curve25519-dalek-derive",
"digest",
"digest 0.10.7",
"fiat-crypto",
"rustc_version",
"subtle",
@@ -654,13 +682,22 @@ dependencies = [
"syn",
]
[[package]]
name = "digest"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066"
dependencies = [
"generic-array",
]
[[package]]
name = "digest"
version = "0.10.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
dependencies = [
"block-buffer",
"block-buffer 0.10.4",
"crypto-common",
"subtle",
]
@@ -682,6 +719,16 @@ version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d6add3b8cff394282be81f3fc1a0605db594ed69890078ca6e2cab1c408bcf04"
[[package]]
name = "ed25519"
version = "1.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "91cff35c70bba8a626e3185d8cd48cc11b5437e1a5bcd15b9b5fa3c64b6dfee7"
dependencies = [
"serde",
"signature 1.6.4",
]
[[package]]
name = "ed25519"
version = "2.2.3"
@@ -689,7 +736,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53"
dependencies = [
"pkcs8",
"signature",
"signature 2.2.0",
]
[[package]]
name = "ed25519-dalek"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d"
dependencies = [
"curve25519-dalek 3.2.0",
"ed25519 1.5.3",
"rand 0.7.3",
"serde",
"serde_bytes",
"sha2 0.9.9",
"zeroize",
]
[[package]]
@@ -698,11 +760,11 @@ version = "2.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4a3daa8e81a3963a60642bcc1f90a670680bd4a77535faa384e9d1c79d620871"
dependencies = [
"curve25519-dalek",
"ed25519",
"curve25519-dalek 4.1.3",
"ed25519 2.2.3",
"rand_core 0.6.4",
"serde",
"sha2",
"sha2 0.10.9",
"subtle",
"zeroize",
]
@@ -713,21 +775,30 @@ version = "1.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
[[package]]
name = "encoding_rs"
version = "0.8.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3"
dependencies = [
"cfg-if",
]
[[package]]
name = "engineioxide"
version = "0.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fb6d2ef56d20b87b7f02bc08935e21bd7cfd88da6b82b129d5d89a28ddf3a389"
dependencies = [
"base64",
"base64 0.22.1",
"bytes",
"engineioxide-core",
"futures-core",
"futures-util",
"http 1.3.1",
"http-body",
"http-body 1.0.1",
"http-body-util",
"hyper",
"hyper 1.6.0",
"hyper-util",
"itoa",
"memchr",
@@ -750,7 +821,7 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "04e5d58eb7374df380cbb53ef65f9c35f544c9c217528adb1458c8df05978475"
dependencies = [
"base64",
"base64 0.22.1",
"bytes",
"rand 0.9.1",
"serde",
@@ -805,6 +876,12 @@ dependencies = [
"pin-project-lite",
]
[[package]]
name = "fastrand"
version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
[[package]]
name = "fiat-crypto"
version = "0.2.9"
@@ -823,6 +900,21 @@ version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
[[package]]
name = "foreign-types"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
dependencies = [
"foreign-types-shared",
]
[[package]]
name = "foreign-types-shared"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
[[package]]
name = "form_urlencoded"
version = "1.2.1"
@@ -983,6 +1075,17 @@ dependencies = [
"version_check",
]
[[package]]
name = "getrandom"
version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce"
dependencies = [
"cfg-if",
"libc",
"wasi 0.9.0+wasi-snapshot-preview1",
]
[[package]]
name = "getrandom"
version = "0.2.16"
@@ -1026,6 +1129,22 @@ version = "0.31.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f"
[[package]]
name = "gsio-client"
version = "0.1.0"
dependencies = [
"chrono",
"futures",
"reqwest",
"serde",
"serde_json",
"thiserror 1.0.69",
"tokio",
"tracing",
"tracing-subscriber",
"uuid",
]
[[package]]
name = "gsio-node"
version = "0.1.0"
@@ -1037,7 +1156,7 @@ dependencies = [
"rmpv",
"serde",
"serde_json",
"sha2",
"sha2 0.10.9",
"socketioxide",
"tokio",
"tower-http",
@@ -1058,6 +1177,43 @@ dependencies = [
"worker-macros",
]
[[package]]
name = "gsio-wallet"
version = "0.1.0"
dependencies = [
"chrono",
"ed25519-dalek 1.0.1",
"hex",
"rand 0.7.3",
"rand_core 0.5.1",
"serde",
"serde_json",
"thiserror 1.0.69",
"tokio",
"tracing",
"tracing-subscriber",
"uuid",
]
[[package]]
name = "h2"
version = "0.3.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8"
dependencies = [
"bytes",
"fnv",
"futures-core",
"futures-sink",
"futures-util",
"http 0.2.12",
"indexmap",
"slab",
"tokio",
"tokio-util",
"tracing",
]
[[package]]
name = "h2"
version = "0.4.10"
@@ -1100,6 +1256,12 @@ version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c"
[[package]]
name = "hex"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
[[package]]
name = "hickory-proto"
version = "0.25.0-alpha.5"
@@ -1162,7 +1324,7 @@ version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e"
dependencies = [
"digest",
"digest 0.10.7",
]
[[package]]
@@ -1187,6 +1349,17 @@ dependencies = [
"itoa",
]
[[package]]
name = "http-body"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2"
dependencies = [
"bytes",
"http 0.2.12",
"pin-project-lite",
]
[[package]]
name = "http-body"
version = "1.0.1"
@@ -1206,7 +1379,7 @@ dependencies = [
"bytes",
"futures-core",
"http 1.3.1",
"http-body",
"http-body 1.0.1",
"pin-project-lite",
]
@@ -1222,6 +1395,30 @@ version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
[[package]]
name = "hyper"
version = "0.14.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41dfc780fdec9373c01bae43289ea34c972e40ee3c9f6b3c8801a35f35586ce7"
dependencies = [
"bytes",
"futures-channel",
"futures-core",
"futures-util",
"h2 0.3.26",
"http 0.2.12",
"http-body 0.4.6",
"httparse",
"httpdate",
"itoa",
"pin-project-lite",
"socket2",
"tokio",
"tower-service",
"tracing",
"want",
]
[[package]]
name = "hyper"
version = "1.6.0"
@@ -1231,9 +1428,9 @@ dependencies = [
"bytes",
"futures-channel",
"futures-util",
"h2",
"h2 0.4.10",
"http 1.3.1",
"http-body",
"http-body 1.0.1",
"httparse",
"httpdate",
"itoa",
@@ -1243,6 +1440,19 @@ dependencies = [
"want",
]
[[package]]
name = "hyper-tls"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905"
dependencies = [
"bytes",
"hyper 0.14.32",
"native-tls",
"tokio",
"tokio-native-tls",
]
[[package]]
name = "hyper-util"
version = "0.1.14"
@@ -1254,8 +1464,8 @@ dependencies = [
"futures-core",
"futures-util",
"http 1.3.1",
"http-body",
"hyper",
"http-body 1.0.1",
"hyper 1.6.0",
"libc",
"pin-project-lite",
"socket2",
@@ -1423,7 +1633,7 @@ dependencies = [
"netlink-proto",
"netlink-sys",
"rtnetlink",
"system-configuration",
"system-configuration 0.6.1",
"tokio",
"windows 0.53.0",
]
@@ -1440,7 +1650,7 @@ dependencies = [
"futures",
"http 1.3.1",
"http-body-util",
"hyper",
"hyper 1.6.0",
"hyper-util",
"log",
"rand 0.8.5",
@@ -1639,12 +1849,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fbb68ea10844211a59ce46230909fd0ea040e8a192454d4cc2ee0d53e12280eb"
dependencies = [
"bs58",
"ed25519-dalek",
"ed25519-dalek 2.1.1",
"hkdf",
"multihash",
"quick-protobuf",
"rand 0.8.5",
"sha2",
"sha2 0.10.9",
"thiserror 2.0.12",
"tracing",
"zeroize",
@@ -2086,6 +2296,23 @@ dependencies = [
"unsigned-varint 0.7.2",
]
[[package]]
name = "native-tls"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e"
dependencies = [
"libc",
"log",
"openssl",
"openssl-probe",
"openssl-sys",
"schannel",
"security-framework",
"security-framework-sys",
"tempfile",
]
[[package]]
name = "netlink-packet-core"
version = "0.7.0"
@@ -2261,6 +2488,50 @@ version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381"
[[package]]
name = "openssl"
version = "0.10.73"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8505734d46c8ab1e19a1dce3aef597ad87dcb4c37e7188231769bd6bd51cebf8"
dependencies = [
"bitflags 2.9.1",
"cfg-if",
"foreign-types",
"libc",
"once_cell",
"openssl-macros",
"openssl-sys",
]
[[package]]
name = "openssl-macros"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "openssl-probe"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e"
[[package]]
name = "openssl-sys"
version = "0.9.109"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90096e2e47630d78b7d1c20952dc621f957103f8bc2c8359ec81290d75238571"
dependencies = [
"cc",
"libc",
"pkg-config",
"vcpkg",
]
[[package]]
name = "overload"
version = "0.1.1"
@@ -2308,7 +2579,7 @@ version = "3.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38af38e8470ac9dee3ce1bae1af9c1671fffc44ddfd8bd1d0a3445bf349a8ef3"
dependencies = [
"base64",
"base64 0.22.1",
"serde",
]
@@ -2360,6 +2631,12 @@ dependencies = [
"spki",
]
[[package]]
name = "pkg-config"
version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c"
[[package]]
name = "polling"
version = "3.8.0"
@@ -2553,6 +2830,19 @@ version = "5.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5"
[[package]]
name = "rand"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
dependencies = [
"getrandom 0.1.16",
"libc",
"rand_chacha 0.2.2",
"rand_core 0.5.1",
"rand_hc",
]
[[package]]
name = "rand"
version = "0.8.5"
@@ -2574,6 +2864,16 @@ dependencies = [
"rand_core 0.9.3",
]
[[package]]
name = "rand_chacha"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
dependencies = [
"ppv-lite86",
"rand_core 0.5.1",
]
[[package]]
name = "rand_chacha"
version = "0.3.1"
@@ -2594,6 +2894,15 @@ dependencies = [
"rand_core 0.9.3",
]
[[package]]
name = "rand_core"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
dependencies = [
"getrandom 0.1.16",
]
[[package]]
name = "rand_core"
version = "0.6.4"
@@ -2612,6 +2921,15 @@ dependencies = [
"getrandom 0.3.3",
]
[[package]]
name = "rand_hc"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
dependencies = [
"rand_core 0.5.1",
]
[[package]]
name = "rcgen"
version = "0.13.2"
@@ -2678,6 +2996,46 @@ version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
[[package]]
name = "reqwest"
version = "0.11.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62"
dependencies = [
"base64 0.21.7",
"bytes",
"encoding_rs",
"futures-core",
"futures-util",
"h2 0.3.26",
"http 0.2.12",
"http-body 0.4.6",
"hyper 0.14.32",
"hyper-tls",
"ipnet",
"js-sys",
"log",
"mime",
"native-tls",
"once_cell",
"percent-encoding",
"pin-project-lite",
"rustls-pemfile",
"serde",
"serde_json",
"serde_urlencoded",
"sync_wrapper 0.1.2",
"system-configuration 0.5.1",
"tokio",
"tokio-native-tls",
"tower-service",
"url",
"wasm-bindgen",
"wasm-bindgen-futures",
"web-sys",
"winreg",
]
[[package]]
name = "resolv-conf"
version = "0.7.4"
@@ -2795,6 +3153,15 @@ dependencies = [
"zeroize",
]
[[package]]
name = "rustls-pemfile"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c"
dependencies = [
"base64 0.21.7",
]
[[package]]
name = "rustls-pki-types"
version = "1.12.0"
@@ -2858,6 +3225,15 @@ dependencies = [
"winapi-util",
]
[[package]]
name = "schannel"
version = "0.1.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d"
dependencies = [
"windows-sys 0.59.0",
]
[[package]]
name = "scoped-tls"
version = "1.0.1"
@@ -2870,6 +3246,29 @@ version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]]
name = "security-framework"
version = "2.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02"
dependencies = [
"bitflags 2.9.1",
"core-foundation",
"core-foundation-sys",
"libc",
"security-framework-sys",
]
[[package]]
name = "security-framework-sys"
version = "2.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49db231d56a190491cb4aeda9527f1ad45345af50b0851622a7adb8c03b01c32"
dependencies = [
"core-foundation-sys",
"libc",
]
[[package]]
name = "semver"
version = "1.0.26"
@@ -2907,6 +3306,15 @@ dependencies = [
"wasm-bindgen",
]
[[package]]
name = "serde_bytes"
version = "0.11.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8437fd221bde2d4ca316d61b90e337e9e702b3820b87d63caa9ba6c02bd06d96"
dependencies = [
"serde",
]
[[package]]
name = "serde_derive"
version = "1.0.219"
@@ -2960,7 +3368,20 @@ checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba"
dependencies = [
"cfg-if",
"cpufeatures",
"digest",
"digest 0.10.7",
]
[[package]]
name = "sha2"
version = "0.9.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800"
dependencies = [
"block-buffer 0.9.0",
"cfg-if",
"cpufeatures",
"digest 0.9.0",
"opaque-debug",
]
[[package]]
@@ -2971,7 +3392,7 @@ checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283"
dependencies = [
"cfg-if",
"cpufeatures",
"digest",
"digest 0.10.7",
]
[[package]]
@@ -2989,6 +3410,12 @@ version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
[[package]]
name = "signature"
version = "1.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c"
[[package]]
name = "signature"
version = "2.2.0"
@@ -3025,11 +3452,11 @@ dependencies = [
"aes-gcm",
"blake2",
"chacha20poly1305",
"curve25519-dalek",
"curve25519-dalek 4.1.3",
"rand_core 0.6.4",
"ring",
"rustc_version",
"sha2",
"sha2 0.10.9",
"subtle",
]
@@ -3054,8 +3481,8 @@ dependencies = [
"futures-core",
"futures-util",
"http 1.3.1",
"http-body",
"hyper",
"http-body 1.0.1",
"hyper 1.6.0",
"matchit 0.8.4",
"pin-project-lite",
"serde",
@@ -3135,6 +3562,12 @@ dependencies = [
"unicode-ident",
]
[[package]]
name = "sync_wrapper"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160"
[[package]]
name = "sync_wrapper"
version = "1.0.2"
@@ -3152,6 +3585,17 @@ dependencies = [
"syn",
]
[[package]]
name = "system-configuration"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7"
dependencies = [
"bitflags 1.3.2",
"core-foundation",
"system-configuration-sys 0.5.0",
]
[[package]]
name = "system-configuration"
version = "0.6.1"
@@ -3160,7 +3604,17 @@ checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b"
dependencies = [
"bitflags 2.9.1",
"core-foundation",
"system-configuration-sys",
"system-configuration-sys 0.6.0",
]
[[package]]
name = "system-configuration-sys"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9"
dependencies = [
"core-foundation-sys",
"libc",
]
[[package]]
@@ -3179,6 +3633,19 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b2093cf4c8eb1e67749a6762251bc9cd836b6fc171623bd0a9d324d37af2417"
[[package]]
name = "tempfile"
version = "3.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e8a64e3985349f2441a1a9ef0b853f869006c3855f2cda6862a94d26ebb9d6a1"
dependencies = [
"fastrand",
"getrandom 0.3.3",
"once_cell",
"rustix",
"windows-sys 0.59.0",
]
[[package]]
name = "thiserror"
version = "1.0.69"
@@ -3311,6 +3778,16 @@ dependencies = [
"syn",
]
[[package]]
name = "tokio-native-tls"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2"
dependencies = [
"native-tls",
"tokio",
]
[[package]]
name = "tokio-tungstenite"
version = "0.26.2"
@@ -3345,7 +3822,7 @@ dependencies = [
"futures-core",
"futures-util",
"pin-project-lite",
"sync_wrapper",
"sync_wrapper 1.0.2",
"tokio",
"tower-layer",
"tower-service",
@@ -3361,7 +3838,7 @@ dependencies = [
"bitflags 2.9.1",
"bytes",
"http 1.3.1",
"http-body",
"http-body 1.0.1",
"pin-project-lite",
"tower-layer",
"tower-service",
@@ -3552,6 +4029,12 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65"
[[package]]
name = "vcpkg"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
[[package]]
name = "version_check"
version = "0.9.5"
@@ -3577,6 +4060,12 @@ dependencies = [
"try-lock",
]
[[package]]
name = "wasi"
version = "0.9.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
[[package]]
name = "wasi"
version = "0.11.1+wasi-snapshot-preview1"
@@ -4076,7 +4565,7 @@ dependencies = [
"futures-channel",
"futures-util",
"http 1.3.1",
"http-body",
"http-body 1.0.1",
"js-sys",
"matchit 0.7.3",
"pin-project",
@@ -4150,7 +4639,7 @@ version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7e468321c81fb07fa7f4c636c3972b9100f0346e5b6a9f2bd0603a52f7ed277"
dependencies = [
"curve25519-dalek",
"curve25519-dalek 4.1.3",
"rand_core 0.6.4",
"serde",
"zeroize",

View File

@@ -1,5 +1,7 @@
[workspace]
members = [
"crates/gsio-relay",
'crates/gsio-node'
'crates/gsio-node',
"crates/gsio-client",
"crates/gsio-wallet"
]

View File

@@ -3,11 +3,12 @@
[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](https://opensource.org/licenses/MIT)
gsio-net is a distributed ledger system with three main components:
gsio-net is a distributed ledger system with four main components:
1. **gsio-node**: A Rust-based Socket.IO server that handles real-time communication
2. **gsio-relay**: A Rust-based WebSocket server implemented as a Cloudflare Worker
3. **gsio-node-client**: A TypeScript client for connecting to the gsio-node server
4. **gsio-wallet**: A Rust-based wallet library for managing keys, transactions, and balances
## Project Overview
@@ -271,6 +272,55 @@ The WebSocket client provides the following functions for participating in the p
});
```
### Using the Wallet
The gsio-wallet library provides the following functions for managing wallets and transactions:
- **Creating a new wallet**:
```rust
use gsio_wallet::Wallet;
// Create a new empty wallet
let mut wallet = Wallet::new();
// Generate a new keypair and get the address
let address = wallet.generate_keypair().unwrap();
println!("New wallet address: {}", address);
```
- **Creating and signing a transaction**:
```rust
use gsio_wallet::{Wallet, TransactionType};
use serde_json::json;
// Create a transaction
let mut transaction = wallet.create_transaction(
&sender_address,
&recipient_address,
100, // amount
10, // fee
TransactionType::Transfer,
Some(json!({"memo": "Payment for services"}))
).unwrap();
// Sign the transaction
wallet.sign_transaction(&mut transaction).unwrap();
```
- **Submitting a transaction**:
```rust
// Submit the transaction to the network
let transaction_id = wallet.submit_transaction(&transaction).await.unwrap();
println!("Transaction submitted with ID: {}", transaction_id);
```
- **Checking account balance**:
```rust
// Get account balance
let balance = wallet.get_balance(&address).unwrap();
println!("Account balance: {}", balance);
```
## Development
### Project Structure
@@ -280,6 +330,8 @@ The WebSocket client provides the following functions for participating in the p
- **src/ledger.rs**: Distributed ledger implementation
- **src/p2p.rs**: Peer-to-peer networking implementation
- **gsio-relay/**: WebSocket server implemented as a Cloudflare Worker
- **gsio-wallet/**: Wallet library for managing keys and transactions
- **src/lib.rs**: Wallet implementation with key management and transaction handling
- **packages/**: Contains TypeScript packages
- **gsio-node-client/**: Client for connecting to the gsio-node server
- **src/listeners/node_listener.ts**: Socket.IO client for ledger operations
@@ -304,6 +356,17 @@ The p2p networking is implemented in `crates/gsio-node/src/p2p.rs` and provides
- **Connection Management**: Connections are managed using Socket.IO
- **Ledger Synchronization**: Nodes can request and receive ledger entries from other nodes
### Wallet System
The wallet system is implemented in `crates/gsio-wallet/src/lib.rs` and provides the following features:
- **Key Management**: Generate and store cryptographic keypairs (using Ed25519)
- **Account Management**: Create and manage accounts with addresses derived from public keys
- **Transaction Creation**: Create various types of transactions (Transfer, Stake, Unstake)
- **Transaction Signing**: Sign transactions with the account's private key
- **Balance Tracking**: Track account balances and transaction history
- **Secure Storage**: Save and load wallet data securely
### Building Individual Components
- **gsio-node**:
@@ -318,6 +381,12 @@ The p2p networking is implemented in `crates/gsio-node/src/p2p.rs` and provides
cargo install -q worker-build && worker-build --release
```
- **gsio-wallet**:
```bash
cd crates/gsio-wallet
cargo build
```
- **gsio-node-client**:
```bash
cd packages/gsio-node-client
@@ -343,13 +412,8 @@ The p2p networking is implemented in `crates/gsio-node/src/p2p.rs` and provides
- **gsio-node**: Use `RUST_LOG=debug cargo run` for verbose logging.
- **gsio-relay**: Use `wrangler dev --verbose` for detailed logs.
- **gsio-node-client**: Add `console.log` statements for debugging.
- Write more tests
### Cleaning the Project
To clean the project, run:
```bash
npm run clean
```
## Contributing

View File

@@ -0,0 +1,18 @@
[package]
name = "gsio-client"
version = "0.1.0"
publish = false
edition = "2024"
license = "MIT"
[dependencies]
tokio = { version = "1.45.1", features = ["rt-multi-thread", "macros", "time", "net"] }
tracing = { version = "0.1.41" }
tracing-subscriber = { version = "0.3.19", features = ["env-filter"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
uuid = { version = "1.7.0", features = ["v4", "serde"] }
chrono = { version = "0.4.35", features = ["serde"] }
reqwest = { version = "0.11", features = ["json"] }
thiserror = "1.0"
futures = "0.3.31"

View File

@@ -0,0 +1,41 @@
use gsio_client::{GsioClient, GsioClientError};
use serde_json::json;
use tracing_subscriber::FmtSubscriber;
#[tokio::main]
async fn main() -> Result<(), GsioClientError> {
// Initialize tracing
tracing::subscriber::set_global_default(FmtSubscriber::default())
.expect("Failed to set tracing subscriber");
// Create a new client
let client = GsioClient::new("http://localhost:3000")?;
println!("Created GSIO client");
// Add an entry to the ledger
let entry_data = json!({
"message": "Hello, GSIO!",
"timestamp": chrono::Utc::now().to_rfc3339(),
});
let entry = client.add_ledger_entry(entry_data).await?;
println!("Added ledger entry: {:?}", entry);
// Get all entries in the ledger
let entries = client.get_ledger().await?;
println!("Ledger entries:");
for entry in entries {
println!(" - {}: {}", entry.id, entry.data);
}
// Get all known nodes
let nodes = client.get_known_nodes().await?;
println!("Known nodes:");
for node in nodes {
println!(" - {}", node);
}
println!("Example completed successfully");
Ok(())
}

View File

@@ -0,0 +1,138 @@
//! GSIO Client Library
//!
//! This library provides a client for interacting with GSIO nodes.
//! It allows connecting to nodes, adding entries to the ledger,
//! and retrieving ledger data.
use reqwest::{Client as HttpClient, Error as ReqwestError};
use serde::{Deserialize, Serialize};
use serde_json::Value as JsonValue;
use std::time::Duration;
use thiserror::Error;
use tracing::{error, info};
/// Error type for GSIO client operations
#[derive(Error, Debug)]
pub enum GsioClientError {
#[error("HTTP error: {0}")]
HttpError(#[from] ReqwestError),
#[error("JSON serialization error: {0}")]
SerializationError(#[from] serde_json::Error),
#[error("Connection error: {0}")]
ConnectionError(String),
#[error("Server error: {0}")]
ServerError(String),
}
/// A ledger entry
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct LedgerEntry {
pub id: String,
pub timestamp: String,
pub data: JsonValue,
pub node_id: String,
pub hash: String,
}
/// GSIO Client for interacting with GSIO nodes
pub struct GsioClient {
client: HttpClient,
node_url: String,
}
impl GsioClient {
/// Create a new GSIO client
pub fn new(node_url: &str) -> Result<Self, GsioClientError> {
let client = HttpClient::builder()
.timeout(Duration::from_secs(30))
.build()
.map_err(|e| GsioClientError::ConnectionError(e.to_string()))?;
Ok(Self {
client,
node_url: node_url.to_string(),
})
}
/// Add an entry to the ledger
pub async fn add_ledger_entry(&self, data: JsonValue) -> Result<LedgerEntry, GsioClientError> {
info!("Adding ledger entry: {:?}", data);
let url = format!("{}/api/ledger", self.node_url);
let response = self.client.post(&url)
.json(&data)
.send()
.await?;
if !response.status().is_success() {
let error_text = response.text().await?;
return Err(GsioClientError::ServerError(format!("Server returned error: {}", error_text)));
}
let entry: LedgerEntry = response.json().await?;
Ok(entry)
}
/// Get all entries in the ledger
pub async fn get_ledger(&self) -> Result<Vec<LedgerEntry>, GsioClientError> {
info!("Getting ledger entries");
let url = format!("{}/api/ledger", self.node_url);
let response = self.client.get(&url)
.send()
.await?;
if !response.status().is_success() {
let error_text = response.text().await?;
return Err(GsioClientError::ServerError(format!("Server returned error: {}", error_text)));
}
let entries: Vec<LedgerEntry> = response.json().await?;
Ok(entries)
}
/// Get all known nodes in the network
pub async fn get_known_nodes(&self) -> Result<Vec<String>, GsioClientError> {
info!("Getting known nodes");
let url = format!("{}/api/nodes", self.node_url);
let response = self.client.get(&url)
.send()
.await?;
if !response.status().is_success() {
let error_text = response.text().await?;
return Err(GsioClientError::ServerError(format!("Server returned error: {}", error_text)));
}
let data: JsonValue = response.json().await?;
let nodes = data.get("nodes")
.ok_or_else(|| GsioClientError::ServerError("Invalid response format".to_string()))?;
let nodes: Vec<String> = serde_json::from_value(nodes.clone())?;
Ok(nodes)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_client_creation() {
let client = GsioClient::new("http://localhost:3000").unwrap();
assert_eq!(client.node_url, "http://localhost:3000");
}
// More tests would be added here in a real implementation
}

View File

@@ -0,0 +1,20 @@
[package]
name = "gsio-wallet"
version = "0.1.0"
publish = false
edition = "2024"
license = "MIT"
[dependencies]
tokio = { version = "1.45.1", features = ["rt-multi-thread", "macros", "time"] }
tracing = { version = "0.1.41" }
tracing-subscriber = { version = "0.3.19", features = ["env-filter"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
uuid = { version = "1.7.0", features = ["v4", "serde"] }
chrono = { version = "0.4.35", features = ["serde"] }
thiserror = "1.0"
rand = "0.7.3"
rand_core = "0.5.1"
ed25519-dalek = { version = "1.0.1", features = ["serde"] }
hex = "0.4.3"

View File

@@ -0,0 +1,65 @@
# GSIO Wallet
A wallet implementation for the GSIO network.
## Features
- Key management (generate, store, retrieve keys)
- Transaction creation and signing
- Balance tracking
- Transaction history
## Usage
```rust
use gsio_wallet::{Wallet, TransactionType};
// Create a new wallet
let mut wallet = Wallet::new();
// Generate a new keypair
let address = wallet.generate_keypair().unwrap();
println!("Generated address: {}", address);
// Create a transaction
let transaction = wallet.create_transaction(
&address,
"recipient_address",
100,
10,
TransactionType::Transfer,
None,
).unwrap();
// Sign the transaction
let mut signed_transaction = transaction.clone();
wallet.sign_transaction(&mut signed_transaction).unwrap();
// Submit the transaction (in an async context)
async {
let tx_id = wallet.submit_transaction(&signed_transaction).await.unwrap();
println!("Transaction submitted: {}", tx_id);
};
// Get account balance
let balance = wallet.get_balance(&address).unwrap();
println!("Balance: {}", balance);
// Get transaction history
let history = wallet.get_transaction_history(&address).unwrap();
println!("Transaction history: {:?}", history);
```
## Implementation Details
This is a stubbed implementation of a wallet for the GSIO network. The actual implementation would need to be integrated with the GSIO network to handle real transactions and balances.
The wallet uses Ed25519 for cryptographic operations, which provides strong security for digital signatures.
## Future Improvements
- Implement wallet persistence with encryption
- Add support for multiple accounts in a single wallet
- Implement transaction verification
- Add support for different transaction types
- Integrate with the GSIO network for real transactions

View File

@@ -0,0 +1,256 @@
//! GSIO Wallet Library
//!
//! This library provides wallet functionality for the GSIO network.
//! It allows creating and managing wallets, generating and storing keys,
//! signing transactions, and tracking balances.
use chrono::{DateTime, Utc};
use ed25519_dalek::{Keypair, PublicKey, SecretKey, Signature, Signer, SignatureError};
use rand::rngs::OsRng;
use serde::{Deserialize, Serialize};
use serde_json::Value as JsonValue;
use std::collections::HashMap;
use std::fs::{self, File};
use std::io::{self, Read, Write};
use std::path::{Path, PathBuf};
use thiserror::Error;
use tracing::{debug, error, info};
use uuid::Uuid;
/// Error type for GSIO wallet operations
#[derive(Error, Debug)]
pub enum WalletError {
#[error("IO error: {0}")]
IoError(#[from] io::Error),
#[error("JSON serialization error: {0}")]
SerializationError(#[from] serde_json::Error),
#[error("Signature error: {0}")]
SignatureError(#[from] SignatureError),
#[error("Key not found: {0}")]
KeyNotFound(String),
#[error("Wallet not found: {0}")]
WalletNotFound(String),
#[error("Invalid wallet data: {0}")]
InvalidWalletData(String),
#[error("Insufficient funds: required {0}, available {1}")]
InsufficientFunds(u64, u64),
}
/// Transaction type
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum TransactionType {
Transfer,
Stake,
Unstake,
// Other transaction types can be added here
}
/// Transaction status
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum TransactionStatus {
Pending,
Confirmed,
Failed,
}
/// Transaction record
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Transaction {
pub id: String,
pub transaction_type: TransactionType,
pub amount: u64,
pub fee: u64,
pub sender: String,
pub recipient: String,
pub timestamp: DateTime<Utc>,
pub status: TransactionStatus,
pub signature: Option<String>,
pub data: Option<JsonValue>,
}
/// Wallet account information
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Account {
pub address: String,
pub public_key: String,
pub balance: u64,
pub nonce: u64,
pub transactions: Vec<String>,
}
/// GSIO Wallet for managing keys and transactions
pub struct Wallet {
keypair: Option<Keypair>,
accounts: HashMap<String, Account>,
wallet_path: Option<PathBuf>,
}
impl Wallet {
/// Create a new empty wallet
pub fn new() -> Self {
Self {
keypair: None,
accounts: HashMap::new(),
wallet_path: None,
}
}
/// Generate a new keypair
pub fn generate_keypair(&mut self) -> Result<String, WalletError> {
let mut csprng = OsRng;
let keypair = Keypair::generate(&mut csprng);
let address = format!("gsio_{}", hex::encode(&keypair.public.to_bytes()[0..20]));
self.keypair = Some(keypair);
// Create a new account for this keypair
let account = Account {
address: address.clone(),
public_key: hex::encode(self.keypair.as_ref().unwrap().public.to_bytes()),
balance: 0,
nonce: 0,
transactions: Vec::new(),
};
self.accounts.insert(address.clone(), account);
Ok(address)
}
/// Load wallet from file
pub fn load(&mut self, path: &Path) -> Result<(), WalletError> {
// This is a stub implementation
info!("Loading wallet from: {:?}", path);
self.wallet_path = Some(path.to_path_buf());
// In a real implementation, this would load the wallet data from the file
// For now, we'll just return Ok to indicate success
Ok(())
}
/// Save wallet to file
pub fn save(&self) -> Result<(), WalletError> {
// This is a stub implementation
if let Some(path) = &self.wallet_path {
info!("Saving wallet to: {:?}", path);
// In a real implementation, this would save the wallet data to the file
} else {
return Err(WalletError::IoError(io::Error::new(
io::ErrorKind::NotFound,
"Wallet path not set",
)));
}
// For now, we'll just return Ok to indicate success
Ok(())
}
/// Get account by address
pub fn get_account(&self, address: &str) -> Result<&Account, WalletError> {
self.accounts
.get(address)
.ok_or_else(|| WalletError::WalletNotFound(address.to_string()))
}
/// Get account balance
pub fn get_balance(&self, address: &str) -> Result<u64, WalletError> {
let account = self.get_account(address)?;
Ok(account.balance)
}
/// Create a new transaction
pub fn create_transaction(
&self,
sender: &str,
recipient: &str,
amount: u64,
fee: u64,
transaction_type: TransactionType,
data: Option<JsonValue>,
) -> Result<Transaction, WalletError> {
// Check if sender account exists
let sender_account = self.get_account(sender)?;
// Check if sender has enough funds
if sender_account.balance < amount + fee {
return Err(WalletError::InsufficientFunds(
amount + fee,
sender_account.balance,
));
}
// Create transaction
let transaction = Transaction {
id: Uuid::new_v4().to_string(),
transaction_type,
amount,
fee,
sender: sender.to_string(),
recipient: recipient.to_string(),
timestamp: Utc::now(),
status: TransactionStatus::Pending,
signature: None,
data,
};
Ok(transaction)
}
/// Sign a transaction
pub fn sign_transaction(&self, transaction: &mut Transaction) -> Result<(), WalletError> {
// This is a stub implementation
if self.keypair.is_none() {
return Err(WalletError::KeyNotFound("No keypair loaded".to_string()));
}
// In a real implementation, this would sign the transaction with the keypair
// For now, we'll just set a dummy signature
transaction.signature = Some("dummy_signature".to_string());
Ok(())
}
/// Submit a transaction to the network
pub async fn submit_transaction(&self, transaction: &Transaction) -> Result<String, WalletError> {
// This is a stub implementation
info!("Submitting transaction: {:?}", transaction);
// In a real implementation, this would submit the transaction to the network
// For now, we'll just return the transaction ID to indicate success
Ok(transaction.id.clone())
}
/// Get transaction history for an account
pub fn get_transaction_history(&self, address: &str) -> Result<Vec<String>, WalletError> {
let account = self.get_account(address)?;
Ok(account.transactions.clone())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_wallet_creation() {
let wallet = Wallet::new();
assert!(wallet.keypair.is_none());
assert!(wallet.accounts.is_empty());
}
#[test]
fn test_keypair_generation() {
let mut wallet = Wallet::new();
let address = wallet.generate_keypair().unwrap();
assert!(wallet.keypair.is_some());
assert!(wallet.accounts.contains_key(&address));
}
// More tests would be added here in a real implementation
}