{"id":19107355,"url":"https://github.com/smartcontractkit/wsrpc","last_synced_at":"2025-10-11T05:02:45.742Z","repository":{"id":43084757,"uuid":"366678757","full_name":"smartcontractkit/wsrpc","owner":"smartcontractkit","description":"A bi-directional Websockets RPC library ","archived":false,"fork":false,"pushed_at":"2025-03-20T16:23:33.000Z","size":3549,"stargazers_count":11,"open_issues_count":5,"forks_count":5,"subscribers_count":107,"default_branch":"main","last_synced_at":"2025-04-19T08:10:37.340Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/smartcontractkit.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2021-05-12T10:33:02.000Z","updated_at":"2025-03-20T16:23:38.000Z","dependencies_parsed_at":"2023-12-11T23:17:14.842Z","dependency_job_id":"438fac5a-c276-4262-b217-8117d5747c8b","html_url":"https://github.com/smartcontractkit/wsrpc","commit_stats":null,"previous_names":[],"tags_count":28,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smartcontractkit%2Fwsrpc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smartcontractkit%2Fwsrpc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smartcontractkit%2Fwsrpc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smartcontractkit%2Fwsrpc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/smartcontractkit","download_url":"https://codeload.github.com/smartcontractkit/wsrpc/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251765260,"owners_count":21640160,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-09T04:12:16.689Z","updated_at":"2025-10-11T05:02:45.623Z","avatar_url":"https://github.com/smartcontractkit.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Websockets RPC\n\nEstablishes a persistent bi-directional communication channel using mTLS and websockets.\n\n## Set up\n\nIn order to generate a service definition you will need the wsrpc protoc plugin.\n\nBuild the protoc plugin\n\n```\ncd cmd/protoc-gen-go-wsrpc\ngo build\n```\n\nPlace the resulting binary in your GOPATH.\n\nIn the directory containing your protobuf service definition, run:\n\n```\nprotoc --go_out=. --go_opt=paths=source_relative \\\n--go-wsrpc_out=. \\\n--go-wsrpc_opt=paths=source_relative yourproto.proto\n```\n\nThis will generate the service definitions in *_wsrpc.pb.go\n\n## Usage\n\n### Client to Server RPC\n\nImplement handlers for the server\n```go\ntype pingServer struct {}\n\nfunc (s *pingServer) Ping(ctx context.Context, req *pb.PingRequest) (*pb.PingResponse, error) {\n\t// Extracts the connection client's public key.\n\t// You can use this to identify the client\n\tp, ok := peer.FromContext(ctx)\n\tif !ok {\n\t\treturn nil, errors.New(\"could not extract public key\")\n\t}\n\tpubKey := p.PublicKey\n\n\tfmt.Println(pubKey)\n\n\treturn \u0026pb.PingResponse{\n\t\tBody: \"Pong\",\n\t}, nil\n}\n```\n\nInitialize a server with the server's private key and a slice of allowable public keys.\n\n```go\nlis, err := net.Listen(\"tcp\", \"127.0.0.1:1337\")\nif err != nil {\n\tlog.Fatalf(\"[MAIN] failed to listen: %v\", err)\n}\ns := wsrpc.NewServer(wsrpc.Creds(privKey, pubKeys))\n// Register the ping server implementation with the wsrpc server\npb.RegisterPingServer(s, \u0026pingServer{})\n\ns.Serve(lis)\n```\n\nInitialize a client with the client's private key and the server's public key\n\n```go\nconn, err := wsrpc.Dial(\"127.0.0.1:1338\", wsrpc.WithTransportCreds(privKey, serverPubKey))\nif err != nil {\n\tlog.Fatalln(err)\n}\ndefer conn.Close()\n\n// Initialize a new wsrpc client caller\n// This is used to called RPC methods on the server\nc := pb.NewPingClient(conn)\n\nc.Ping(context.Background(), \u0026pb.Ping{Body: \"Ping\"})\n```\n\n### Server to Client RPC\n\nImplement handlers for the client\n\n```go\ntype pingClient struct{}\n\nfunc (c *pingClient) Ping(ctx context.Context, req *pb.PingRequest) (*pb.PingResponse, error) {\n\treturn \u0026pb.PingResponse{\n\t\tBody: \"Pong\",\n\t}, nil\n}\n```\n\nInitialize a server with the server's private key and a slice of allowable public keys.\n\n```go\nlis, err := net.Listen(\"tcp\", \"127.0.0.1:1337\")\nif err != nil {\n\tlog.Fatalf(\"[MAIN] failed to listen: %v\", err)\n}\ns := wsrpc.NewServer(wsrpc.Creds(privKey, pubKeys))\nc := pb.NewPingClient(s)\n\ns.Serve(lis)\n\n// Call the RPC method with the pub key so we know which connection to send it to\n// otherwise it will error.\nctx := peer.NewCallContext(context.Background(), pubKey)\nc.Ping(ctx, \u0026pb.PingRequest{Body: \"Ping\"})\n```\n\nInitialize a client with the client's private key and the server's public key\n\n```go\nconn, err := wsrpc.Dial(\"127.0.0.1:1337\", wsrpc.WithTransportCreds(privKey, serverPubKey))\nif err != nil {\n\tlog.Fatalln(err)\n}\ndefer conn.Close()\n\n// Initialize RPC call handlers on the client connection\npb.RegisterPingServer(conn, \u0026pingClient{})\n```\n\n## Example\n\nYou can run a simple example where both the client and server implement a Ping service, and perform RPC calls to each other every 5 seconds.\n\n1. Run the server in `examples/simple/server` with `go run main.go`\n2. Run a client (Alice) in `examples/simple/server` with `go run main.go 0`\n3. Run a client (Bob) in `examples/simple/server` with `go run main.go 1`\n4. Run a invalid client (Charlie) in `examples/simple/server` with `go run main.go 2`. The server will reject this connection.\n\nWhile the client's are connected, kill the server and see the client's enter a backoff retry loop. Start the server again and they will reconnect.\n\n## TODO\n\n- [ ] Improve Tests\n- [ ] Return a response status\n- [x] Add a Blocking DialOption\n\n## Release Process\n\nThe release process for this package is based off [smartcontractkit/releng-go-lib](https://github.com/smartcontractkit/releng-go-lib). This release process leverages [changesets](https://github.com/changesets/changesets).\n\n### Setup\n\n- Install `pnpm` ([pnpm.io/installation](https://pnpm.io/installation))\n- Run `pnpm install`\n\n### General usage\n\nDuring a regular change, include a `changeset` file in the PR by running `pnpm changeset`. It will prompt you for a description of the change, and whether the change is a major/minor/patch version bump.\n\nThis will create a file in the `.changeset` directory. When a release is created this file will be \"consumed\", applying the version bump, and including the change's description to the release's notes.\n\n### Creating a release\n\nWhen `changeset` files are present on the main branch, there will be a persistent pull request open. This pull request \"consumes\" the changeset files, and bumps the version in `package.json`.\nWhen this PR is merged, the automated workflow running against `main` will create a tag and release.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsmartcontractkit%2Fwsrpc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsmartcontractkit%2Fwsrpc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsmartcontractkit%2Fwsrpc/lists"}