forked from decentral1se/iroh-go
Compare commits
27 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
412c2f48ea
|
|||
|
b60f37f85e
|
|||
|
68ad06fe2a
|
|||
|
14a1ebf8d8
|
|||
|
c4522df071
|
|||
|
0858f533fa
|
|||
|
b2c2f9363c
|
|||
|
c668dd01d8
|
|||
|
d8668c7949
|
|||
|
f3c78b79ff
|
|||
|
0da4eb7dd2
|
|||
|
e7f90ff4f6
|
|||
|
c151d398bc
|
|||
|
7162741cb0
|
|||
|
6be98f24b7
|
|||
|
fcd131a0e4
|
|||
| a2494e624c | |||
| a163d5bf07 | |||
| d63e45f746 | |||
| 1affee6df6 | |||
| caf52e915d | |||
| 186f3ac9aa | |||
| 931465c83e | |||
|
1a469c4ae9
|
|||
|
23211c0ba6
|
|||
|
1c18b9265f
|
|||
| e9a0e0be63 |
+8
-1
@@ -1,2 +1,9 @@
|
||||
iroh-go/target/
|
||||
.*.sw[a-z]
|
||||
examples/connect-desktop/build
|
||||
examples/connect-desktop/frontend/dist
|
||||
examples/connect-desktop/frontend/wailsjs
|
||||
examples/connect/connect
|
||||
examples/errors/errors
|
||||
examples/pairchat/pairchat
|
||||
examples/timeserve/timeserve
|
||||
iroh-go/target/
|
||||
|
||||
@@ -1,18 +1,92 @@
|
||||
# iroh-go
|
||||
# `iroh-go`
|
||||
|
||||
> **WARNING** Extremely Experimental ™️
|
||||
> **WARNING** Highly Experimental ™️
|
||||
|
||||
Go bindings for [`iroh-ffi`](https://github.com/n0-computer/iroh-ffi). They're
|
||||
ready for testing but due to [this
|
||||
issue](https://github.com/n0-computer/iroh-ffi/issues/248#issuecomment-4777541073),
|
||||
there are surely unknown horrors awaiting you deep inside the `staticlib`. It's
|
||||
a work in progress but you can yeet some bytes across the interwebz Right Now
|
||||
✅
|
||||
Go FFI bindings for [`iroh`](https://iroh.computer) via
|
||||
[`iroh-ffi`](https://github.com/n0-computer/iroh-ffi).
|
||||
|
||||
## Motivation
|
||||
|
||||
The goal is to provide, as far as possible, seamless "just `go build` it"
|
||||
support for Go iroh hackers without requiring them to deal with shared
|
||||
libraries, the Rust toolchain or a deepdive in how FFI works. The current
|
||||
approach is to embed `libiroh` as a `staticlib` built with Rust for each
|
||||
platform. We use [`musl`](https://musl.libc.org) to avoid `glibc`
|
||||
incompatibilities on different linux systems. It's then possible to build a
|
||||
static binary with `go build` or [with
|
||||
Zig](https://dev.to/kristoff/zig-makes-go-cross-compilation-just-work-29ho).
|
||||
`iroh-go` does require `CGO_ENABLED=1`.
|
||||
|
||||
## Platform support
|
||||
|
||||
* `x86_64-unknown-linux-musl`
|
||||
* `aarch64-unknown-linux-musl`
|
||||
|
||||
## Documentation
|
||||
|
||||
See [`docs.rs`](https://docs.rs/iroh/1.0.0/iroh/) for the original Rust API
|
||||
documentation. The exposed Go API is 1:1. Here's the Go bindings documentation
|
||||
on [`godocs.io`](https://godocs.io/git.coopcloud.tech/decentral1se/iroh-go).
|
||||
|
||||
## Examples
|
||||
|
||||
See [`examples`](./examples).
|
||||
|
||||
## Rebuild `iroh-ffi`
|
||||
## Run your own `iroh-relay`
|
||||
|
||||
`./scripts/generate.sh`
|
||||
See [`iroh-relay`](https://git.coopcloud.tech/decentral1se/iroh-relay) if you
|
||||
want more small footprint static binary goodness. You can also make use of the
|
||||
upstream provided docker image: `n0computer/iroh-relay`.
|
||||
|
||||
### Local hacking
|
||||
|
||||
First, run `iroh-relay` in development mode with noisy logging.
|
||||
|
||||
```
|
||||
RUST_LOG=info,iroh_relay=debug ./iroh-relay --dev
|
||||
```
|
||||
|
||||
You can then use `http://localhost:3340` as the default location of your own
|
||||
relay in the construction of your endpoint as follows. Once you create an
|
||||
endpoint, you should see your relay respond locally with corresponding logs.
|
||||
|
||||
```go
|
||||
preset := iroh.PresetN0DisableRelay()
|
||||
relay, _ := iroh.RelayModeCustomFromUrls([]string{"http://localhost:3340"})
|
||||
opts := iroh.EndpointOptions{
|
||||
Preset: &preset,
|
||||
RelayMode: &relay,
|
||||
// ...moar config...
|
||||
}
|
||||
```
|
||||
|
||||
## Generate bindings
|
||||
|
||||
See [`iroh-go`](./iroh-go) for the Rust toolchain configuration. Run
|
||||
`./scripts/generate.sh` to build a new set of libraries which end up vendored
|
||||
in [`libs`](./libs).
|
||||
|
||||
## Who is using it?
|
||||
|
||||
* [`iroh-tracker`](https://git.coopcloud.tech/cblgh/iroh-tracker)
|
||||
|
||||
## Known issues
|
||||
|
||||
* We need to patch the upstream `iroh-ffi` `endpoint.rs` to fix an
|
||||
incompatibility with
|
||||
[`uniffi-bindgen-go`](https://github.com/NordSecurity/uniffi-bindgen-go). See
|
||||
[this
|
||||
commit](https://github.com/decentral1se/iroh-ffi/commit/3e102569e1c348480416a9b05cf020760f607dfe)
|
||||
for more.
|
||||
* We need to patch the upstream `iroh-ffi` `Cargo.toml` to remove the
|
||||
`crate-type` configuration when runnings builds here. See [this
|
||||
commit](https://github.com/decentral1se/iroh-ffi/commit/207e5d7cd7dee6eab350d3aad85029431a63ca3f)
|
||||
for more.
|
||||
* Error handling is extremely inconvenient due to
|
||||
[`iroh-ffi#263`](https://github.com/n0-computer/iroh-ffi/issues/263).
|
||||
Proposals for improvement are very welcome.
|
||||
|
||||
## Licenses
|
||||
|
||||
Apache 2.0 & MIT, following the upstream licensing choices in
|
||||
[`iroh-ffi`](https://github.com/n0-computer/iroh-ffi).
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
package iroh_ffi
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// As casts an error to IrohError and back, extracting relevant error message
|
||||
// information. It is a single argument variant of the typical errors.As API
|
||||
// because we always expect an IrohError back from the iroh FFI bindings. The
|
||||
// bindings do not return an IrohError for reasons and will not for the
|
||||
// forseeable future due to API stability guarantees.
|
||||
func As(err error) error {
|
||||
if err, ok := errors.AsType[IrohError](err); ok {
|
||||
return errors.New(fmt.Sprintf("%s: %s", err.Message(), err.DebugMessage()))
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// Is suports matching against the stable iroh error taxonomy using the error
|
||||
// sentinel construction below. The caller must pass in a valid error sentinel
|
||||
// specified by this library, e.g. iroh.BindError.
|
||||
func (e *IrohError) Is(target error) bool {
|
||||
if err, ok := errors.AsType[sentinel](target); ok {
|
||||
return uint(e.Kind()) == err.kind
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
type sentinel struct {
|
||||
kind uint
|
||||
message string
|
||||
}
|
||||
|
||||
func (s sentinel) Error() string {
|
||||
return s.message
|
||||
}
|
||||
|
||||
var InvalidInputError error = sentinel{
|
||||
kind: uint(IrohErrorKindInvalidInput),
|
||||
message: "iroh: invalid input supplied by the caller",
|
||||
}
|
||||
|
||||
var BindError error = sentinel{
|
||||
kind: uint(IrohErrorKindBind),
|
||||
message: "iroh: failure while initiating or completing an outgoing connection",
|
||||
}
|
||||
|
||||
var ConnectError error = sentinel{
|
||||
kind: uint(IrohErrorKindConnect),
|
||||
message: "iroh: failure while initiating or completing an outgoing connectio",
|
||||
}
|
||||
|
||||
var ConnectionError error = sentinel{
|
||||
kind: uint(IrohErrorKindConnection),
|
||||
message: "iroh: an established connection failed or closed unexpectedly",
|
||||
}
|
||||
|
||||
var AlpnError error = sentinel{
|
||||
kind: uint(IrohErrorKindAlpn),
|
||||
message: "iroh: ALPN negotiation or lookup failed",
|
||||
}
|
||||
|
||||
var KeyParsingError error = sentinel{
|
||||
kind: uint(IrohErrorKindKeyParsing),
|
||||
message: "iroh: endpoint id / public key parsing failed",
|
||||
}
|
||||
|
||||
var TicketParsingError error = sentinel{
|
||||
kind: uint(IrohErrorKindKeyParsing),
|
||||
message: "iroh: ticket parsing failed",
|
||||
}
|
||||
|
||||
var RelayError error = sentinel{
|
||||
kind: uint(IrohErrorKindRelay),
|
||||
message: "iroh: stream read/write/control operation failed",
|
||||
}
|
||||
|
||||
var StreamError error = sentinel{
|
||||
kind: uint(IrohErrorKindStream),
|
||||
message: "iroh: datagram send/receive operation failed",
|
||||
}
|
||||
|
||||
var DatagramError error = sentinel{
|
||||
kind: uint(IrohErrorKindDatagram),
|
||||
message: "iroh: datagram send/receive operation failed",
|
||||
}
|
||||
|
||||
var FCallbackError error = sentinel{
|
||||
kind: uint(IrohErrorKindCallback),
|
||||
message: "iroh: foreign callback failed",
|
||||
}
|
||||
|
||||
var ClosedError error = sentinel{
|
||||
kind: uint(IrohErrorKindClosed),
|
||||
message: "iroh: operation was attempted on a closed stream/connection/resource",
|
||||
}
|
||||
|
||||
var TimeoutError error = sentinel{
|
||||
kind: uint(IrohErrorKindTimeout),
|
||||
message: "iroh: operation timed out",
|
||||
}
|
||||
|
||||
var InternalError error = sentinel{
|
||||
kind: uint(IrohErrorKindInternal),
|
||||
message: "iroh: unclassified internal error",
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
build/bin
|
||||
node_modules
|
||||
frontend/dist
|
||||
@@ -0,0 +1,61 @@
|
||||
# connect-desktop
|
||||
|
||||
A version of [`../connect`](../connect) as a desktop application. On running
|
||||
the desktop application, an Iroh endpoint id will be displayed. This id can be
|
||||
plugged into a terminal running the [`../connect`](../connect) example as a
|
||||
sender. What the sender types in the terminal will appear in the
|
||||
connect-desktop application window.
|
||||
|
||||
## Dependencies
|
||||
|
||||
* Wails v2.10.2 (old version, haven't tried on a newer yet - hopefully works there too!)
|
||||
* Vite v3.0.7
|
||||
* Go v1.18
|
||||
* npm v10.2+
|
||||
* node v20.11+
|
||||
|
||||
**Getting setup**
|
||||
|
||||
* Install node and golang
|
||||
|
||||
Install Wails:
|
||||
|
||||
```
|
||||
go install github.com/wailsapp/wails/v2/cmd/wails@v2.10.2 // for tested version
|
||||
// OR: go install github.com/wailsapp/wails/v2/cmd/wails@latest // for latest
|
||||
|
||||
// then install frontend dependency
|
||||
cd frontend
|
||||
npm i
|
||||
```
|
||||
|
||||
## Running in development mode
|
||||
|
||||
```
|
||||
wails dev
|
||||
```
|
||||
|
||||
## Build a binary
|
||||
|
||||
```
|
||||
wails build .
|
||||
```
|
||||
|
||||
## Listener (this example)
|
||||
|
||||
```
|
||||
./connect-desktop
|
||||
```
|
||||
|
||||
## Terminal 2 (sender)
|
||||
|
||||
Run [`../connect`](../connect) in a terminal and connect to the endpoint id
|
||||
displayed by the listener.
|
||||
|
||||
```
|
||||
./connect -endpoint <endpoint-id>
|
||||
```
|
||||
|
||||
You'll see a connection notice if the two endpoints manage to connect to each
|
||||
other. You can type messages in the sender terminal and they will be shown on
|
||||
the screen of the desktop app.
|
||||
@@ -0,0 +1,94 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
iroh "git.coopcloud.tech/decentral1se/iroh-go"
|
||||
"github.com/wailsapp/wails/v2/pkg/runtime"
|
||||
|
||||
)
|
||||
|
||||
var (
|
||||
alpn = []byte("iroh-go-hello-world/0")
|
||||
frameSize uint32 = 256
|
||||
endpointPeer *string
|
||||
)
|
||||
|
||||
func check(err error) {
|
||||
if err != nil {
|
||||
irohErr := err.(*iroh.IrohError)
|
||||
panic(irohErr.Message())
|
||||
}
|
||||
}
|
||||
|
||||
// App struct
|
||||
type App struct {
|
||||
ctx context.Context
|
||||
endpoint *iroh.Endpoint
|
||||
}
|
||||
|
||||
// NewApp creates a new App application struct
|
||||
func NewApp() *App {
|
||||
return &App{}
|
||||
}
|
||||
|
||||
// startup is called when the app starts. The context is saved
|
||||
// so we can call the runtime methods
|
||||
func (a *App) startup(ctx context.Context) {
|
||||
a.ctx = ctx
|
||||
|
||||
preset := iroh.PresetN0()
|
||||
opts := iroh.EndpointOptions{
|
||||
Preset: &preset,
|
||||
Alpns: &[][]byte{alpn},
|
||||
}
|
||||
|
||||
endpoint, err := iroh.EndpointBind(opts)
|
||||
check(err)
|
||||
endpoint.Online()
|
||||
a.endpoint = endpoint
|
||||
|
||||
listen(a.ctx, a.endpoint)
|
||||
}
|
||||
|
||||
func (a *App) GetEndpointIDString() string {
|
||||
return a.endpoint.Id().String()
|
||||
}
|
||||
|
||||
func listen(ctx context.Context, e *iroh.Endpoint) {
|
||||
for {
|
||||
incoming := *e.AcceptNext()
|
||||
go handleIncoming(ctx, incoming)
|
||||
}
|
||||
}
|
||||
|
||||
func handleIncoming (ctx context.Context, incoming *iroh.Incoming) {
|
||||
accepting, err := incoming.Accept()
|
||||
check(err)
|
||||
|
||||
conn, err := accepting.Connect()
|
||||
check(err)
|
||||
|
||||
stream, err := conn.AcceptBi()
|
||||
check(err)
|
||||
|
||||
recv := stream.Recv()
|
||||
for {
|
||||
frame, err := recv.Read(frameSize)
|
||||
// handle timeout
|
||||
if err != nil {
|
||||
irohErr := err.(*iroh.IrohError)
|
||||
errMsg := irohErr.Message()
|
||||
if strings.HasPrefix(errMsg, "ConnectionLost") {
|
||||
fmt.Println("lost connection")
|
||||
break
|
||||
} else {
|
||||
check(err)
|
||||
}
|
||||
}
|
||||
runtime.EventsEmit(ctx, "data", map[string]interface{}{
|
||||
"data": string(frame),
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8"/>
|
||||
<meta content="width=device-width, initial-scale=1.0" name="viewport"/>
|
||||
<title>go-iroh-desktop-example</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script src="./src/main.js" type="module"></script>
|
||||
</body>
|
||||
</html>
|
||||
+627
@@ -0,0 +1,627 @@
|
||||
{
|
||||
"name": "frontend",
|
||||
"version": "0.0.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "frontend",
|
||||
"version": "0.0.0",
|
||||
"devDependencies": {
|
||||
"vite": "^3.0.7"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/android-arm": {
|
||||
"version": "0.15.18",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.15.18.tgz",
|
||||
"integrity": "sha512-5GT+kcs2WVGjVs7+boataCkO5Fg0y4kCjzkB5bAip7H4jfnOS3dA6KPiww9W1OEKTKeAcUVhdZGvgI65OXmUnw==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-loong64": {
|
||||
"version": "0.15.18",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.15.18.tgz",
|
||||
"integrity": "sha512-L4jVKS82XVhw2nvzLg/19ClLWg0y27ulRwuP7lcyL6AbUWB5aPglXY3M21mauDQMDfRLs8cQmeT03r/+X3cZYQ==",
|
||||
"cpu": [
|
||||
"loong64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/es-errors": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
|
||||
"integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/esbuild": {
|
||||
"version": "0.15.18",
|
||||
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.15.18.tgz",
|
||||
"integrity": "sha512-x/R72SmW3sSFRm5zrrIjAhCeQSAWoni3CmHEqfQrZIQTM3lVCdehdwuIqaOtfC2slvpdlLa62GYoN8SxT23m6Q==",
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"bin": {
|
||||
"esbuild": "bin/esbuild"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@esbuild/android-arm": "0.15.18",
|
||||
"@esbuild/linux-loong64": "0.15.18",
|
||||
"esbuild-android-64": "0.15.18",
|
||||
"esbuild-android-arm64": "0.15.18",
|
||||
"esbuild-darwin-64": "0.15.18",
|
||||
"esbuild-darwin-arm64": "0.15.18",
|
||||
"esbuild-freebsd-64": "0.15.18",
|
||||
"esbuild-freebsd-arm64": "0.15.18",
|
||||
"esbuild-linux-32": "0.15.18",
|
||||
"esbuild-linux-64": "0.15.18",
|
||||
"esbuild-linux-arm": "0.15.18",
|
||||
"esbuild-linux-arm64": "0.15.18",
|
||||
"esbuild-linux-mips64le": "0.15.18",
|
||||
"esbuild-linux-ppc64le": "0.15.18",
|
||||
"esbuild-linux-riscv64": "0.15.18",
|
||||
"esbuild-linux-s390x": "0.15.18",
|
||||
"esbuild-netbsd-64": "0.15.18",
|
||||
"esbuild-openbsd-64": "0.15.18",
|
||||
"esbuild-sunos-64": "0.15.18",
|
||||
"esbuild-windows-32": "0.15.18",
|
||||
"esbuild-windows-64": "0.15.18",
|
||||
"esbuild-windows-arm64": "0.15.18"
|
||||
}
|
||||
},
|
||||
"node_modules/esbuild-android-64": {
|
||||
"version": "0.15.18",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.15.18.tgz",
|
||||
"integrity": "sha512-wnpt3OXRhcjfIDSZu9bnzT4/TNTDsOUvip0foZOUBG7QbSt//w3QV4FInVJxNhKc/ErhUxc5z4QjHtMi7/TbgA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/esbuild-android-arm64": {
|
||||
"version": "0.15.18",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.15.18.tgz",
|
||||
"integrity": "sha512-G4xu89B8FCzav9XU8EjsXacCKSG2FT7wW9J6hOc18soEHJdtWu03L3TQDGf0geNxfLTtxENKBzMSq9LlbjS8OQ==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/esbuild-darwin-64": {
|
||||
"version": "0.15.18",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.15.18.tgz",
|
||||
"integrity": "sha512-2WAvs95uPnVJPuYKP0Eqx+Dl/jaYseZEUUT1sjg97TJa4oBtbAKnPnl3b5M9l51/nbx7+QAEtuummJZW0sBEmg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/esbuild-darwin-arm64": {
|
||||
"version": "0.15.18",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.15.18.tgz",
|
||||
"integrity": "sha512-tKPSxcTJ5OmNb1btVikATJ8NftlyNlc8BVNtyT/UAr62JFOhwHlnoPrhYWz09akBLHI9nElFVfWSTSRsrZiDUA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/esbuild-freebsd-64": {
|
||||
"version": "0.15.18",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.15.18.tgz",
|
||||
"integrity": "sha512-TT3uBUxkteAjR1QbsmvSsjpKjOX6UkCstr8nMr+q7zi3NuZ1oIpa8U41Y8I8dJH2fJgdC3Dj3CXO5biLQpfdZA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"freebsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/esbuild-freebsd-arm64": {
|
||||
"version": "0.15.18",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.15.18.tgz",
|
||||
"integrity": "sha512-R/oVr+X3Tkh+S0+tL41wRMbdWtpWB8hEAMsOXDumSSa6qJR89U0S/PpLXrGF7Wk/JykfpWNokERUpCeHDl47wA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"freebsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/esbuild-linux-32": {
|
||||
"version": "0.15.18",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.15.18.tgz",
|
||||
"integrity": "sha512-lphF3HiCSYtaa9p1DtXndiQEeQDKPl9eN/XNoBf2amEghugNuqXNZA/ZovthNE2aa4EN43WroO0B85xVSjYkbg==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/esbuild-linux-64": {
|
||||
"version": "0.15.18",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.15.18.tgz",
|
||||
"integrity": "sha512-hNSeP97IviD7oxLKFuii5sDPJ+QHeiFTFLoLm7NZQligur8poNOWGIgpQ7Qf8Balb69hptMZzyOBIPtY09GZYw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/esbuild-linux-arm": {
|
||||
"version": "0.15.18",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.15.18.tgz",
|
||||
"integrity": "sha512-UH779gstRblS4aoS2qpMl3wjg7U0j+ygu3GjIeTonCcN79ZvpPee12Qun3vcdxX+37O5LFxz39XeW2I9bybMVA==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/esbuild-linux-arm64": {
|
||||
"version": "0.15.18",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.15.18.tgz",
|
||||
"integrity": "sha512-54qr8kg/6ilcxd+0V3h9rjT4qmjc0CccMVWrjOEM/pEcUzt8X62HfBSeZfT2ECpM7104mk4yfQXkosY8Quptug==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/esbuild-linux-mips64le": {
|
||||
"version": "0.15.18",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.15.18.tgz",
|
||||
"integrity": "sha512-Mk6Ppwzzz3YbMl/ZZL2P0q1tnYqh/trYZ1VfNP47C31yT0K8t9s7Z077QrDA/guU60tGNp2GOwCQnp+DYv7bxQ==",
|
||||
"cpu": [
|
||||
"mips64el"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/esbuild-linux-ppc64le": {
|
||||
"version": "0.15.18",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.15.18.tgz",
|
||||
"integrity": "sha512-b0XkN4pL9WUulPTa/VKHx2wLCgvIAbgwABGnKMY19WhKZPT+8BxhZdqz6EgkqCLld7X5qiCY2F/bfpUUlnFZ9w==",
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/esbuild-linux-riscv64": {
|
||||
"version": "0.15.18",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.15.18.tgz",
|
||||
"integrity": "sha512-ba2COaoF5wL6VLZWn04k+ACZjZ6NYniMSQStodFKH/Pu6RxzQqzsmjR1t9QC89VYJxBeyVPTaHuBMCejl3O/xg==",
|
||||
"cpu": [
|
||||
"riscv64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/esbuild-linux-s390x": {
|
||||
"version": "0.15.18",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.15.18.tgz",
|
||||
"integrity": "sha512-VbpGuXEl5FCs1wDVp93O8UIzl3ZrglgnSQ+Hu79g7hZu6te6/YHgVJxCM2SqfIila0J3k0csfnf8VD2W7u2kzQ==",
|
||||
"cpu": [
|
||||
"s390x"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/esbuild-netbsd-64": {
|
||||
"version": "0.15.18",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.15.18.tgz",
|
||||
"integrity": "sha512-98ukeCdvdX7wr1vUYQzKo4kQ0N2p27H7I11maINv73fVEXt2kyh4K4m9f35U1K43Xc2QGXlzAw0K9yoU7JUjOg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"netbsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/esbuild-openbsd-64": {
|
||||
"version": "0.15.18",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.15.18.tgz",
|
||||
"integrity": "sha512-yK5NCcH31Uae076AyQAXeJzt/vxIo9+omZRKj1pauhk3ITuADzuOx5N2fdHrAKPxN+zH3w96uFKlY7yIn490xQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"openbsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/esbuild-sunos-64": {
|
||||
"version": "0.15.18",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.15.18.tgz",
|
||||
"integrity": "sha512-On22LLFlBeLNj/YF3FT+cXcyKPEI263nflYlAhz5crxtp3yRG1Ugfr7ITyxmCmjm4vbN/dGrb/B7w7U8yJR9yw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"sunos"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/esbuild-windows-32": {
|
||||
"version": "0.15.18",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.15.18.tgz",
|
||||
"integrity": "sha512-o+eyLu2MjVny/nt+E0uPnBxYuJHBvho8vWsC2lV61A7wwTWC3jkN2w36jtA+yv1UgYkHRihPuQsL23hsCYGcOQ==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/esbuild-windows-64": {
|
||||
"version": "0.15.18",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.15.18.tgz",
|
||||
"integrity": "sha512-qinug1iTTaIIrCorAUjR0fcBk24fjzEedFYhhispP8Oc7SFvs+XeW3YpAKiKp8dRpizl4YYAhxMjlftAMJiaUw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/esbuild-windows-arm64": {
|
||||
"version": "0.15.18",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.15.18.tgz",
|
||||
"integrity": "sha512-q9bsYzegpZcLziq0zgUi5KqGVtfhjxGbnksaBFYmWLxeV/S1fK4OLdq2DFYnXcLMjlZw2L0jLsk1eGoB522WXQ==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/fsevents": {
|
||||
"version": "2.3.3",
|
||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
|
||||
"integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/function-bind": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
|
||||
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
|
||||
"dev": true,
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/hasown": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz",
|
||||
"integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"function-bind": "^1.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/is-core-module": {
|
||||
"version": "2.16.2",
|
||||
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.2.tgz",
|
||||
"integrity": "sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"hasown": "^2.0.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/nanoid": {
|
||||
"version": "3.3.15",
|
||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.15.tgz",
|
||||
"integrity": "sha512-y7Wygv/7mEOvxTuEQDB8StXdMRBWf1kR/tlhAzBRUFkB2jfcLOAxO/SHmOO2zgz1pVgK29/kyupn059/bCHdjA==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ai"
|
||||
}
|
||||
],
|
||||
"bin": {
|
||||
"nanoid": "bin/nanoid.cjs"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/path-parse": {
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
|
||||
"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/picocolors": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
|
||||
"integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/postcss": {
|
||||
"version": "8.5.15",
|
||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.15.tgz",
|
||||
"integrity": "sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/postcss/"
|
||||
},
|
||||
{
|
||||
"type": "tidelift",
|
||||
"url": "https://tidelift.com/funding/github/npm/postcss"
|
||||
},
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ai"
|
||||
}
|
||||
],
|
||||
"dependencies": {
|
||||
"nanoid": "^3.3.12",
|
||||
"picocolors": "^1.1.1",
|
||||
"source-map-js": "^1.2.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^10 || ^12 || >=14"
|
||||
}
|
||||
},
|
||||
"node_modules/resolve": {
|
||||
"version": "1.22.12",
|
||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.12.tgz",
|
||||
"integrity": "sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"es-errors": "^1.3.0",
|
||||
"is-core-module": "^2.16.1",
|
||||
"path-parse": "^1.0.7",
|
||||
"supports-preserve-symlinks-flag": "^1.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"resolve": "bin/resolve"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/rollup": {
|
||||
"version": "2.80.0",
|
||||
"resolved": "https://registry.npmjs.org/rollup/-/rollup-2.80.0.tgz",
|
||||
"integrity": "sha512-cIFJOD1DESzpjOBl763Kp1AH7UE/0fcdHe6rZXUdQ9c50uvgigvW97u3IcSeBwOkgqL/PXPBktBCh0KEu5L8XQ==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"rollup": "dist/bin/rollup"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10.0.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"fsevents": "~2.3.2"
|
||||
}
|
||||
},
|
||||
"node_modules/source-map-js": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
|
||||
"integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/supports-preserve-symlinks-flag": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
|
||||
"integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/vite": {
|
||||
"version": "3.2.11",
|
||||
"resolved": "https://registry.npmjs.org/vite/-/vite-3.2.11.tgz",
|
||||
"integrity": "sha512-K/jGKL/PgbIgKCiJo5QbASQhFiV02X9Jh+Qq0AKCRCRKZtOTVi4t6wh75FDpGf2N9rYOnzH87OEFQNaFy6pdxQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"esbuild": "^0.15.9",
|
||||
"postcss": "^8.4.18",
|
||||
"resolve": "^1.22.1",
|
||||
"rollup": "^2.79.1"
|
||||
},
|
||||
"bin": {
|
||||
"vite": "bin/vite.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.18.0 || >=16.0.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"fsevents": "~2.3.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/node": ">= 14",
|
||||
"less": "*",
|
||||
"sass": "*",
|
||||
"stylus": "*",
|
||||
"sugarss": "*",
|
||||
"terser": "^5.4.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/node": {
|
||||
"optional": true
|
||||
},
|
||||
"less": {
|
||||
"optional": true
|
||||
},
|
||||
"sass": {
|
||||
"optional": true
|
||||
},
|
||||
"stylus": {
|
||||
"optional": true
|
||||
},
|
||||
"sugarss": {
|
||||
"optional": true
|
||||
},
|
||||
"terser": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"name": "frontend",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vite build",
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"devDependencies": {
|
||||
"vite": "^3.0.7"
|
||||
}
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
5fbf12469d224a93954efecb5886e8a6
|
||||
@@ -0,0 +1,41 @@
|
||||
import './style.css';
|
||||
|
||||
import { GetEndpointIDString } from '../wailsjs/go/main/App';
|
||||
import { EventsOn } from "../wailsjs/runtime/runtime";
|
||||
|
||||
document.querySelector('#app').innerHTML = `
|
||||
<div class="result" id="result">loading endpoint id...</div>
|
||||
<div class="messages" id="messages"></div>
|
||||
`;
|
||||
|
||||
let resultElement = document.getElementById("result");
|
||||
|
||||
EventsOn("data", ({ data }) => {
|
||||
const m = document.getElementById("messages")
|
||||
// append to previous output
|
||||
m.innerText = m.innerText + data + "\n"
|
||||
})
|
||||
|
||||
|
||||
function init () {
|
||||
// checky little 1s wait just to let the iroh bits properly initialize
|
||||
setTimeout(() => {
|
||||
try {
|
||||
GetEndpointIDString()
|
||||
.then((result) => {
|
||||
resultElement.innerText = `endpoint id is ${result}`;
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error(err);
|
||||
});
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
}, 1000)
|
||||
}
|
||||
|
||||
if (document.readyState === "loading") {
|
||||
document.addEventListener("DOMContentLoaded", init)
|
||||
} else {
|
||||
init()
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
html {
|
||||
text-align: center;
|
||||
background: black;
|
||||
color: white;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto",
|
||||
"Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
|
||||
sans-serif;
|
||||
}
|
||||
|
||||
#app {
|
||||
display: grid;
|
||||
grid-template-rows: 5rem 1fr;
|
||||
justify-items: center;
|
||||
align-items: center;
|
||||
height: 100vh;
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
module go-iroh-desktop-example
|
||||
|
||||
go 1.26.1
|
||||
|
||||
require (
|
||||
git.coopcloud.tech/decentral1se/iroh-go v0.0.0-20260623204924-1a469c4ae933
|
||||
github.com/wailsapp/wails/v2 v2.10.2
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/bep/debounce v1.2.1 // indirect
|
||||
github.com/go-ole/go-ole v1.3.0 // indirect
|
||||
github.com/godbus/dbus/v5 v5.1.0 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/gorilla/websocket v1.5.3 // indirect
|
||||
github.com/jchv/go-winloader v0.0.0-20210711035445-715c2860da7e // indirect
|
||||
github.com/labstack/echo/v4 v4.13.3 // indirect
|
||||
github.com/labstack/gommon v0.4.2 // indirect
|
||||
github.com/leaanthony/go-ansi-parser v1.6.1 // indirect
|
||||
github.com/leaanthony/gosod v1.0.4 // indirect
|
||||
github.com/leaanthony/slicer v1.6.0 // indirect
|
||||
github.com/leaanthony/u v1.1.1 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/rivo/uniseg v0.4.7 // indirect
|
||||
github.com/samber/lo v1.49.1 // indirect
|
||||
github.com/tkrajina/go-reflector v0.5.8 // indirect
|
||||
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||
github.com/valyala/fasttemplate v1.2.2 // indirect
|
||||
github.com/wailsapp/go-webview2 v1.0.19 // indirect
|
||||
github.com/wailsapp/mimetype v1.4.1 // indirect
|
||||
golang.org/x/crypto v0.33.0 // indirect
|
||||
golang.org/x/net v0.35.0 // indirect
|
||||
golang.org/x/sys v0.30.0 // indirect
|
||||
golang.org/x/text v0.22.0 // indirect
|
||||
)
|
||||
|
||||
replace git.coopcloud.tech/decentral1se/iroh-go => ../../
|
||||
@@ -0,0 +1,81 @@
|
||||
github.com/bep/debounce v1.2.1 h1:v67fRdBA9UQu2NhLFXrSg0Brw7CexQekrBwDMM8bzeY=
|
||||
github.com/bep/debounce v1.2.1/go.mod h1:H8yggRPQKLUhUoqrJC1bO2xNya7vanpDl7xR3ISbCJ0=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE=
|
||||
github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78=
|
||||
github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk=
|
||||
github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
|
||||
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/jchv/go-winloader v0.0.0-20210711035445-715c2860da7e h1:Q3+PugElBCf4PFpxhErSzU3/PY5sFL5Z6rfv4AbGAck=
|
||||
github.com/jchv/go-winloader v0.0.0-20210711035445-715c2860da7e/go.mod h1:alcuEEnZsY1WQsagKhZDsoPCRoOijYqhZvPwLG0kzVs=
|
||||
github.com/labstack/echo/v4 v4.13.3 h1:pwhpCPrTl5qry5HRdM5FwdXnhXSLSY+WE+YQSeCaafY=
|
||||
github.com/labstack/echo/v4 v4.13.3/go.mod h1:o90YNEeQWjDozo584l7AwhJMHN0bOC4tAfg+Xox9q5g=
|
||||
github.com/labstack/gommon v0.4.2 h1:F8qTUNXgG1+6WQmqoUWnz8WiEU60mXVVw0P4ht1WRA0=
|
||||
github.com/labstack/gommon v0.4.2/go.mod h1:QlUFxVM+SNXhDL/Z7YhocGIBYOiwB0mXm1+1bAPHPyU=
|
||||
github.com/leaanthony/debme v1.2.1 h1:9Tgwf+kjcrbMQ4WnPcEIUcQuIZYqdWftzZkBr+i/oOc=
|
||||
github.com/leaanthony/debme v1.2.1/go.mod h1:3V+sCm5tYAgQymvSOfYQ5Xx2JCr+OXiD9Jkw3otUjiA=
|
||||
github.com/leaanthony/go-ansi-parser v1.6.1 h1:xd8bzARK3dErqkPFtoF9F3/HgN8UQk0ed1YDKpEz01A=
|
||||
github.com/leaanthony/go-ansi-parser v1.6.1/go.mod h1:+vva/2y4alzVmmIEpk9QDhA7vLC5zKDTRwfZGOp3IWU=
|
||||
github.com/leaanthony/gosod v1.0.4 h1:YLAbVyd591MRffDgxUOU1NwLhT9T1/YiwjKZpkNFeaI=
|
||||
github.com/leaanthony/gosod v1.0.4/go.mod h1:GKuIL0zzPj3O1SdWQOdgURSuhkF+Urizzxh26t9f1cw=
|
||||
github.com/leaanthony/slicer v1.6.0 h1:1RFP5uiPJvT93TAHi+ipd3NACobkW53yUiBqZheE/Js=
|
||||
github.com/leaanthony/slicer v1.6.0/go.mod h1:o/Iz29g7LN0GqH3aMjWAe90381nyZlDNquK+mtH2Fj8=
|
||||
github.com/leaanthony/u v1.1.1 h1:TUFjwDGlNX+WuwVEzDqQwC2lOv0P4uhTQw7CMFdiK7M=
|
||||
github.com/leaanthony/u v1.1.1/go.mod h1:9+o6hejoRljvZ3BzdYlVL0JYCwtnAsVuN9pVTQcaRfI=
|
||||
github.com/matryer/is v1.4.0/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU=
|
||||
github.com/matryer/is v1.4.1 h1:55ehd8zaGABKLXQUe2awZ99BD/PTc2ls+KV/dXphgEQ=
|
||||
github.com/matryer/is v1.4.1/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU=
|
||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ=
|
||||
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
|
||||
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
||||
github.com/samber/lo v1.49.1 h1:4BIFyVfuQSEpluc7Fua+j1NolZHiEHEpaSEKdsH0tew=
|
||||
github.com/samber/lo v1.49.1/go.mod h1:dO6KHFzUKXgP8LDhU0oI8d2hekjXnGOu0DB8Jecxd6o=
|
||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/tkrajina/go-reflector v0.5.8 h1:yPADHrwmUbMq4RGEyaOUpz2H90sRsETNVpjzo3DLVQQ=
|
||||
github.com/tkrajina/go-reflector v0.5.8/go.mod h1:ECbqLgccecY5kPmPmXg1MrHW585yMcDkVl6IvJe64T4=
|
||||
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||
github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo=
|
||||
github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
|
||||
github.com/wailsapp/go-webview2 v1.0.19 h1:7U3QcDj1PrBPaxJNCui2k1SkWml+Q5kvFUFyTImA6NU=
|
||||
github.com/wailsapp/go-webview2 v1.0.19/go.mod h1:qJmWAmAmaniuKGZPWwne+uor3AHMB5PFhqiK0Bbj8kc=
|
||||
github.com/wailsapp/mimetype v1.4.1 h1:pQN9ycO7uo4vsUUuPeHEYoUkLVkaRntMnHJxVwYhwHs=
|
||||
github.com/wailsapp/mimetype v1.4.1/go.mod h1:9aV5k31bBOv5z6u+QP8TltzvNGJPmNJD4XlAL3U+j3o=
|
||||
github.com/wailsapp/wails/v2 v2.10.2 h1:29U+c5PI4K4hbx8yFbFvwpCuvqK9VgNv8WGobIlKlXk=
|
||||
github.com/wailsapp/wails/v2 v2.10.2/go.mod h1:XuN4IUOPpzBrHUkEd7sCU5ln4T/p1wQedfxP7fKik+4=
|
||||
golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus=
|
||||
golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M=
|
||||
golang.org/x/net v0.0.0-20210505024714-0287a6fb4125/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8=
|
||||
golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk=
|
||||
golang.org/x/sys v0.0.0-20200810151505-1b9f1253b3ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
|
||||
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
|
||||
golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
@@ -0,0 +1,36 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"embed"
|
||||
|
||||
"github.com/wailsapp/wails/v2"
|
||||
"github.com/wailsapp/wails/v2/pkg/options"
|
||||
"github.com/wailsapp/wails/v2/pkg/options/assetserver"
|
||||
)
|
||||
|
||||
//go:embed all:frontend/dist
|
||||
var assets embed.FS
|
||||
|
||||
func main() {
|
||||
// Create an instance of the app structure
|
||||
app := NewApp()
|
||||
|
||||
// Create application with options
|
||||
err := wails.Run(&options.App{
|
||||
Title: "go-iroh-desktop-example",
|
||||
Width: 1024,
|
||||
Height: 768,
|
||||
AssetServer: &assetserver.Options{
|
||||
Assets: assets,
|
||||
},
|
||||
BackgroundColour: &options.RGBA{R: 27, G: 38, B: 54, A: 1},
|
||||
OnStartup: app.startup,
|
||||
Bind: []interface{}{
|
||||
app,
|
||||
},
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
println("Error:", err.Error())
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"$schema": "https://wails.io/schemas/config.v2.json",
|
||||
"name": "connect-desktop-example",
|
||||
"outputfilename": "connect-desktop-example",
|
||||
"frontend:install": "npm install",
|
||||
"frontend:build": "npm run build",
|
||||
"frontend:dev:watcher": "npm run dev",
|
||||
"frontend:dev:serverUrl": "auto",
|
||||
"author": {
|
||||
"name": "cblgh",
|
||||
"email": "source-code@cblgh.org"
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,7 @@
|
||||
t connect
|
||||
# connect
|
||||
|
||||
A simple connection test where one peer can send and the other can receive. See
|
||||
[`../pairchat`](../pairchat) for a more complete bidirectional example.
|
||||
|
||||
## Build a binary
|
||||
|
||||
|
||||
@@ -4,9 +4,9 @@ import (
|
||||
"bufio"
|
||||
"flag"
|
||||
"fmt"
|
||||
"strings"
|
||||
"os"
|
||||
"os/signal"
|
||||
"strings"
|
||||
"syscall"
|
||||
|
||||
iroh "git.coopcloud.tech/decentral1se/iroh-go"
|
||||
@@ -70,7 +70,7 @@ func listen(e *iroh.Endpoint) {
|
||||
}
|
||||
}
|
||||
|
||||
func handleIncoming (incoming *iroh.Incoming) {
|
||||
func handleIncoming(incoming *iroh.Incoming) {
|
||||
accepting, err := incoming.Accept()
|
||||
check(err)
|
||||
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
module git.coopcloud.tech/decentral1se/iroh-go/examples/connect
|
||||
|
||||
go 1.26.1
|
||||
|
||||
require git.coopcloud.tech/decentral1se/iroh-go v0.0.0-20260717110820-68ad06fe2a25
|
||||
|
||||
replace git.coopcloud.tech/decentral1se/iroh-go => ../../
|
||||
@@ -0,0 +1,5 @@
|
||||
# errors
|
||||
|
||||
How to deal with error handling in a convenient way. See
|
||||
[`#263`](https://github.com/n0-computer/iroh-ffi/issues/263) for the juicy
|
||||
details.
|
||||
@@ -0,0 +1,37 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
iroh "git.coopcloud.tech/decentral1se/iroh-go"
|
||||
)
|
||||
|
||||
func main() {
|
||||
preset := iroh.PresetN0DisableRelay()
|
||||
opts := iroh.EndpointOptions{
|
||||
Preset: &preset,
|
||||
Alpns: &[][]byte{[]byte("iroh-go-errors/0")},
|
||||
}
|
||||
|
||||
endpoint, err := iroh.EndpointBind(opts)
|
||||
|
||||
// BEGIN API PREVIEW ZONE
|
||||
|
||||
// 1. convert error to IrohError with As
|
||||
// bring IrohError.Message/DebugMessage back
|
||||
// maintain `err != nil` compatibility
|
||||
if err := iroh.As(err); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// 1. no As machinery required
|
||||
// sentinel check with errors.Is support
|
||||
// works like usual `err`
|
||||
if err != nil && errors.Is(err, iroh.BindError) {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// END API PREVIEW ZONE
|
||||
|
||||
endpoint.Online()
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
module git.coopcloud.tech/decentral1se/iroh-go/examples/errors
|
||||
|
||||
go 1.26.1
|
||||
|
||||
require git.coopcloud.tech/decentral1se/iroh-go v0.0.0-20260717110820-68ad06fe2a25
|
||||
|
||||
replace git.coopcloud.tech/decentral1se/iroh-go => ../../
|
||||
@@ -1,8 +1,8 @@
|
||||
# pairchat
|
||||
|
||||
This is a more complicated version of `examples/connect` which allows the listener to also
|
||||
write back to the sender. The result is a basic pairwise (only 2 peers can connect at once)
|
||||
chat program.
|
||||
This is a more complicated version of [`../connect`](../connect) which allows
|
||||
the listener to also write back to the sender. The result is a basic pairwise
|
||||
(only 2 peers can connect at once) chat program.
|
||||
|
||||
## Build a binary
|
||||
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
module git.coopcloud.tech/decentral1se/iroh-go/examples/pairchat
|
||||
|
||||
go 1.26.1
|
||||
|
||||
require git.coopcloud.tech/decentral1se/iroh-go v0.0.0-20260717110820-68ad06fe2a25
|
||||
|
||||
replace git.coopcloud.tech/decentral1se/iroh-go => ../../
|
||||
@@ -4,9 +4,9 @@ import (
|
||||
"bufio"
|
||||
"flag"
|
||||
"fmt"
|
||||
"strings"
|
||||
"os"
|
||||
"os/signal"
|
||||
"strings"
|
||||
"syscall"
|
||||
|
||||
iroh "git.coopcloud.tech/decentral1se/iroh-go"
|
||||
@@ -61,7 +61,7 @@ func listen(e *iroh.Endpoint) {
|
||||
}
|
||||
}
|
||||
|
||||
func handleIncoming (incoming *iroh.Incoming) {
|
||||
func handleIncoming(incoming *iroh.Incoming) {
|
||||
accepting, err := incoming.Accept()
|
||||
check(err)
|
||||
|
||||
@@ -77,7 +77,7 @@ func handleIncoming (incoming *iroh.Incoming) {
|
||||
go handleReading(recv, done)
|
||||
}
|
||||
|
||||
func handleInput (stream *iroh.BiStream, done chan struct{}) {
|
||||
func handleInput(stream *iroh.BiStream, done chan struct{}) {
|
||||
scanner := bufio.NewScanner(os.Stdin)
|
||||
for scanner.Scan() {
|
||||
if line := scanner.Text(); line != "" {
|
||||
@@ -118,7 +118,6 @@ func handleReading(recv *iroh.RecvStream, done chan struct{}) {
|
||||
close(done)
|
||||
}
|
||||
|
||||
|
||||
func main() {
|
||||
parseFlags()
|
||||
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
# timeserve
|
||||
|
||||
This example demonstrates that an endpoint can support multiple live connections at once. The
|
||||
endpoint aka listener writes the time, once every 2 seconds, to every connected peer.
|
||||
|
||||
Try connecting to a running listener with 3 (or more!) receiver peers at once.
|
||||
|
||||
## Build a binary
|
||||
|
||||
```
|
||||
go build --ldflags '-linkmode external -extldflags=-static -s -w' ./timeserve.go
|
||||
```
|
||||
|
||||
If you run into `glibc` incompatibility, you can compile with `zig`/`musl`.
|
||||
|
||||
```
|
||||
CC="zig cc -target x86_64-linux-musl -lunwind" \
|
||||
CGO_ENABLED=1 \
|
||||
CGO_LDFLAGS="-static" \
|
||||
GOOS=linux GOARCH=amd64 \
|
||||
go build -v -a -ldflags '-extldflags "-static"' ./timeserve.go
|
||||
```
|
||||
|
||||
## Terminal 1 (listener)
|
||||
|
||||
```
|
||||
./timeserve
|
||||
```
|
||||
|
||||
## Terminal 2 (receiver)
|
||||
|
||||
```
|
||||
./timeserve -endpoint <endpoint-id>
|
||||
```
|
||||
|
||||
## Terminal 3 (receiver)
|
||||
|
||||
```
|
||||
./timeserve -endpoint <endpoint-id>
|
||||
```
|
||||
|
||||
You'll see a connection notice if a receiver peer manages to connect to the listener.
|
||||
Receivers (Terminal 2 and Terminal 3) will display the time sent by the listener (Terminal 1).
|
||||
@@ -0,0 +1,7 @@
|
||||
module git.coopcloud.tech/decentral1se/iroh-go/examples/timeserve
|
||||
|
||||
go 1.26.1
|
||||
|
||||
require git.coopcloud.tech/decentral1se/iroh-go v0.0.0-20260717110820-68ad06fe2a25
|
||||
|
||||
replace git.coopcloud.tech/decentral1se/iroh-go => ../../
|
||||
@@ -0,0 +1,139 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/signal"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
iroh "git.coopcloud.tech/decentral1se/iroh-go"
|
||||
)
|
||||
|
||||
var (
|
||||
alpn = []byte("iroh-go-timeserve/0")
|
||||
frameSize uint32 = 256
|
||||
endpointPeer *string
|
||||
)
|
||||
|
||||
func check(err error) {
|
||||
if err != nil {
|
||||
irohErr := err.(*iroh.IrohError)
|
||||
panic(irohErr.Message())
|
||||
}
|
||||
}
|
||||
|
||||
func awaitInterrupt() {
|
||||
done := make(chan os.Signal, 1)
|
||||
signal.Notify(done, syscall.SIGINT, syscall.SIGTERM)
|
||||
<-done
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
func parseFlags() {
|
||||
endpointPeer = flag.String("endpoint", "", "endpoint id of peer")
|
||||
flag.Parse()
|
||||
}
|
||||
|
||||
func receiver(e *iroh.Endpoint, id string) {
|
||||
remote, err := iroh.EndpointIdFromString(id)
|
||||
check(err)
|
||||
|
||||
addr := iroh.NewEndpointAddr(remote, nil, nil)
|
||||
conn, err := e.Connect(addr, alpn)
|
||||
check(err)
|
||||
|
||||
// from docs:
|
||||
// "The peer that calls open_bi must write to its SendStream before the peer Connection is able to accept the stream
|
||||
// using accept_bi()"
|
||||
// https://docs.rs/iroh/latest/iroh/endpoint/struct.Connection.html#method.accept_bi
|
||||
stream, err := conn.OpenBi()
|
||||
check(err)
|
||||
// NOTE: for the other peer to realize the bidi stream is open, you have to send some data! the data sent cannot be
|
||||
// the empty string ""; empty string == no data
|
||||
err = stream.Send().WriteAll([]byte{1})
|
||||
|
||||
check(err)
|
||||
handleReading(stream.Recv())
|
||||
}
|
||||
|
||||
func handleReading(recv *iroh.RecvStream) {
|
||||
for {
|
||||
frame, err := recv.Read(frameSize)
|
||||
if checkForTimeout(err) {
|
||||
break
|
||||
}
|
||||
fmt.Println(string(frame))
|
||||
check(err)
|
||||
}
|
||||
}
|
||||
|
||||
func checkForTimeout(err error) bool {
|
||||
// handle timeout
|
||||
if err != nil {
|
||||
irohErr := err.(*iroh.IrohError)
|
||||
errMsg := irohErr.Message()
|
||||
if strings.HasPrefix(errMsg, "ConnectionLost") {
|
||||
fmt.Println("lost connection")
|
||||
return true
|
||||
} else {
|
||||
// panics and exits bc unhandled err
|
||||
check(err)
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func listen(e *iroh.Endpoint) {
|
||||
for {
|
||||
incoming := *e.AcceptNext()
|
||||
fmt.Println("new connection")
|
||||
go handleIncoming(incoming)
|
||||
}
|
||||
}
|
||||
|
||||
func handleIncoming(incoming *iroh.Incoming) {
|
||||
accepting, err := incoming.Accept()
|
||||
check(err)
|
||||
|
||||
conn, err := accepting.Connect()
|
||||
check(err)
|
||||
|
||||
stream, err := conn.AcceptBi()
|
||||
check(err)
|
||||
|
||||
for {
|
||||
err := stream.Send().WriteAll([]byte(time.Now().Format(time.DateTime)))
|
||||
if checkForTimeout(err) {
|
||||
break
|
||||
}
|
||||
// prints every two seconds (not for any technical reason, 1/sec just feels hectic!)
|
||||
<-time.After(2 * time.Second)
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
parseFlags()
|
||||
|
||||
preset := iroh.PresetN0()
|
||||
opts := iroh.EndpointOptions{
|
||||
Preset: &preset,
|
||||
Alpns: &[][]byte{alpn},
|
||||
}
|
||||
|
||||
endpoint, err := iroh.EndpointBind(opts)
|
||||
check(err)
|
||||
endpoint.Online()
|
||||
|
||||
if *endpointPeer == "" {
|
||||
fmt.Println("this endpoint is online and listening! use this id to connect via a peer:")
|
||||
fmt.Printf("timeserve\n -endpoint %s\n", endpoint.Id())
|
||||
go func() { listen(endpoint) }()
|
||||
} else {
|
||||
go func() { receiver(endpoint, *endpointPeer) }()
|
||||
}
|
||||
|
||||
awaitInterrupt()
|
||||
}
|
||||
Generated
+20
-19
@@ -432,9 +432,9 @@ checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
|
||||
|
||||
[[package]]
|
||||
name = "chacha20"
|
||||
version = "0.10.0"
|
||||
version = "0.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6f8d983286843e49675a4b7a2d174efe136dc93a18d69130dd18198a6c167601"
|
||||
checksum = "d524456ba66e72eb8b115ff89e01e497f8e6d11d78b70b1aa13c0fbd97540a81"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cpufeatures 0.3.0",
|
||||
@@ -1787,7 +1787,8 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "iroh-ffi"
|
||||
version = "1.0.0"
|
||||
version = "1.1.0"
|
||||
source = "git+https://github.com/decentral1se/iroh-ffi?rev=455ba0df43d07b1a28890a70f325b71b05ddeb88#455ba0df43d07b1a28890a70f325b71b05ddeb88"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
@@ -2074,9 +2075,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.102"
|
||||
version = "0.3.103"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "03d04c30968dffe80775bd4d7fb676131cd04a1fb46d2686dbffbaec2d9dfd31"
|
||||
checksum = "53b44bfcdb3f8d5837a46dae1ca9660a837176eee74a28b229bc626816589102"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"futures-util",
|
||||
@@ -4221,9 +4222,9 @@ checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
|
||||
|
||||
[[package]]
|
||||
name = "uuid"
|
||||
version = "1.23.3"
|
||||
version = "1.23.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "144d6b123cef80b301b8f72a9e2ca4370ddec21950d0a103dd22c437006d2db7"
|
||||
checksum = "bf80a72845275afea99e7f2b434723d3bc7e38470fcd1c7ed39a599c73319a53"
|
||||
dependencies = [
|
||||
"getrandom 0.4.3",
|
||||
"js-sys",
|
||||
@@ -4316,9 +4317,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.125"
|
||||
version = "0.2.126"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ddb3f79143bced6de84270411622a2699cee572fc0875aeaf1e7867cf9fca1a"
|
||||
checksum = "4b067c0c11094aef6b7a801c1e34a26affafdf3d051dba08456b868789aaf9a4"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"once_cell",
|
||||
@@ -4329,9 +4330,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-futures"
|
||||
version = "0.4.75"
|
||||
version = "0.4.76"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "503b14d284f2c8dac03b819967e155ea753f573586193b2b2c95990cb5d69280"
|
||||
checksum = "c62df1340f32221cb9c54d6a27b030e3dba64361d4a95bed55f9aacb44da291d"
|
||||
dependencies = [
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
@@ -4339,9 +4340,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.125"
|
||||
version = "0.2.126"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4e21a184b13fb19e157296e2c46056aec9092264fab83e4ba59e68c61b323c3d"
|
||||
checksum = "167ce5e579f6bcf889c4f7175a8a5a585de84e8ff93976ce393efa5f2837aab1"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"wasm-bindgen-macro-support",
|
||||
@@ -4349,9 +4350,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro-support"
|
||||
version = "0.2.125"
|
||||
version = "0.2.126"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fecefd9c35bd935a20fc3fc344b5f29138961e4f47fb03297d88f2587afb5ebd"
|
||||
checksum = "f3997c7839262f4ef12cf90b818d6340c18e80f263f1a94bf157d0ec4420380e"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"proc-macro2",
|
||||
@@ -4362,9 +4363,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.125"
|
||||
version = "0.2.126"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "23939e44bb9a5d7576fa2b563dc2e136628f1224e88a8deed09e04858b77871f"
|
||||
checksum = "dc1b4cb0cc549fcf58d7dfc081778139b3d283a081644e833e84682ad71cea24"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
@@ -4384,9 +4385,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "web-sys"
|
||||
version = "0.3.102"
|
||||
version = "0.3.103"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a6430a72df5eb332242960fe84b3002a241163998241eb596d4f739b9757061d"
|
||||
checksum = "8622dcb61c0bcc9fffa6938bed81210af2da9a7e4a1a834b2e37a59b6dfb6141"
|
||||
dependencies = [
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
|
||||
+1
-10
@@ -8,17 +8,8 @@ publish = false
|
||||
name = "iroh"
|
||||
crate-type = ["staticlib"]
|
||||
|
||||
[[bin]]
|
||||
name = "uniffi-bindgen"
|
||||
path = "src/uniffi-bindgen.rs"
|
||||
|
||||
[dependencies]
|
||||
# NOTE(d1): locally patched with https://github.com/n0-computer/iroh-ffi/pull/254
|
||||
# iroh-ffi = { git = "https://github.com/n0-computer/iroh-ffi" }
|
||||
iroh-ffi = { path = "../../iroh-ffi" }
|
||||
|
||||
# [build-dependencies]
|
||||
# uniffi = { version = "0.31.1", features = ["build"] }
|
||||
iroh-ffi = { git = "https://github.com/decentral1se/iroh-ffi", rev = "455ba0df43d07b1a28890a70f325b71b05ddeb88" }
|
||||
|
||||
[profile.release]
|
||||
codegen-units = 1
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
fn main() {
|
||||
uniffi::uniffi_bindgen_main()
|
||||
}
|
||||
+212
-1
@@ -975,6 +975,15 @@ func uniffiCheckChecksums() {
|
||||
panic("iroh_ffi: uniffi_iroh_ffi_checksum_method_endpointbuilder_apply_n0_disable_relay: UniFFI API checksum mismatch")
|
||||
}
|
||||
}
|
||||
{
|
||||
checksum := rustCall(func(_uniffiStatus *C.RustCallStatus) C.uint16_t {
|
||||
return C.uniffi_iroh_ffi_checksum_method_endpointbuilder_bind()
|
||||
})
|
||||
if checksum != 5850 {
|
||||
// If this happens try cleaning and rebuilding your project
|
||||
panic("iroh_ffi: uniffi_iroh_ffi_checksum_method_endpointbuilder_bind: UniFFI API checksum mismatch")
|
||||
}
|
||||
}
|
||||
{
|
||||
checksum := rustCall(func(_uniffiStatus *C.RustCallStatus) C.uint16_t {
|
||||
return C.uniffi_iroh_ffi_checksum_method_endpointbuilder_bind_addr()
|
||||
@@ -1173,11 +1182,38 @@ func uniffiCheckChecksums() {
|
||||
panic("iroh_ffi: uniffi_iroh_ffi_checksum_method_sendstream_write_all: UniFFI API checksum mismatch")
|
||||
}
|
||||
}
|
||||
{
|
||||
checksum := rustCall(func(_uniffiStatus *C.RustCallStatus) C.uint16_t {
|
||||
return C.uniffi_iroh_ffi_checksum_method_iroherror_debug_message()
|
||||
})
|
||||
if checksum != 33751 {
|
||||
// If this happens try cleaning and rebuilding your project
|
||||
panic("iroh_ffi: uniffi_iroh_ffi_checksum_method_iroherror_debug_message: UniFFI API checksum mismatch")
|
||||
}
|
||||
}
|
||||
{
|
||||
checksum := rustCall(func(_uniffiStatus *C.RustCallStatus) C.uint16_t {
|
||||
return C.uniffi_iroh_ffi_checksum_method_iroherror_is_kind()
|
||||
})
|
||||
if checksum != 10479 {
|
||||
// If this happens try cleaning and rebuilding your project
|
||||
panic("iroh_ffi: uniffi_iroh_ffi_checksum_method_iroherror_is_kind: UniFFI API checksum mismatch")
|
||||
}
|
||||
}
|
||||
{
|
||||
checksum := rustCall(func(_uniffiStatus *C.RustCallStatus) C.uint16_t {
|
||||
return C.uniffi_iroh_ffi_checksum_method_iroherror_kind()
|
||||
})
|
||||
if checksum != 11512 {
|
||||
// If this happens try cleaning and rebuilding your project
|
||||
panic("iroh_ffi: uniffi_iroh_ffi_checksum_method_iroherror_kind: UniFFI API checksum mismatch")
|
||||
}
|
||||
}
|
||||
{
|
||||
checksum := rustCall(func(_uniffiStatus *C.RustCallStatus) C.uint16_t {
|
||||
return C.uniffi_iroh_ffi_checksum_method_iroherror_message()
|
||||
})
|
||||
if checksum != 64767 {
|
||||
if checksum != 60838 {
|
||||
// If this happens try cleaning and rebuilding your project
|
||||
panic("iroh_ffi: uniffi_iroh_ffi_checksum_method_iroherror_message: UniFFI API checksum mismatch")
|
||||
}
|
||||
@@ -1461,6 +1497,15 @@ func uniffiCheckChecksums() {
|
||||
panic("iroh_ffi: uniffi_iroh_ffi_checksum_constructor_endpoint_bind: UniFFI API checksum mismatch")
|
||||
}
|
||||
}
|
||||
{
|
||||
checksum := rustCall(func(_uniffiStatus *C.RustCallStatus) C.uint16_t {
|
||||
return C.uniffi_iroh_ffi_checksum_constructor_endpointbuilder_new()
|
||||
})
|
||||
if checksum != 16347 {
|
||||
// If this happens try cleaning and rebuilding your project
|
||||
panic("iroh_ffi: uniffi_iroh_ffi_checksum_constructor_endpointbuilder_new: UniFFI API checksum mismatch")
|
||||
}
|
||||
}
|
||||
{
|
||||
checksum := rustCall(func(_uniffiStatus *C.RustCallStatus) C.uint16_t {
|
||||
return C.uniffi_iroh_ffi_checksum_constructor_endpointid_from_bytes()
|
||||
@@ -3906,6 +3951,13 @@ type EndpointBuilderInterface interface {
|
||||
ApplyN0()
|
||||
// Replay the n0 preset with relays disabled.
|
||||
ApplyN0DisableRelay()
|
||||
// Consume the builder and bind a new [`Endpoint`].
|
||||
//
|
||||
// The returned `Endpoint` has no protocol handlers — use
|
||||
// [`Endpoint::bind`] with [`EndpointOptions::protocols`] to attach them.
|
||||
// The builder is single-use; a second `bind` returns
|
||||
// `EndpointBuilder already consumed`.
|
||||
Bind() (*Endpoint, error)
|
||||
// Set the address the endpoint binds to (`host:port`).
|
||||
BindAddr(addr string) error
|
||||
// Set the relay mode.
|
||||
@@ -3925,6 +3977,15 @@ type EndpointBuilder struct {
|
||||
ffiObject FfiObject
|
||||
}
|
||||
|
||||
// Create a fresh empty endpoint builder. Apply a preset (`apply_n0`,
|
||||
// `apply_minimal`, `apply_n0_disable_relay`) before [`bind`](Self::bind);
|
||||
// the preset installs the crypto provider, without one `bind` will error.
|
||||
func NewEndpointBuilder() *EndpointBuilder {
|
||||
return FfiConverterEndpointBuilderINSTANCE.Lift(rustCall(func(_uniffiStatus *C.RustCallStatus) C.uint64_t {
|
||||
return C.uniffi_iroh_ffi_fn_constructor_endpointbuilder_new(_uniffiStatus)
|
||||
}))
|
||||
}
|
||||
|
||||
// Set the advertised ALPNs.
|
||||
func (_self *EndpointBuilder) Alpns(alpns [][]byte) {
|
||||
_pointer := _self.ffiObject.incrementPointer("*EndpointBuilder")
|
||||
@@ -3969,6 +4030,45 @@ func (_self *EndpointBuilder) ApplyN0DisableRelay() {
|
||||
})
|
||||
}
|
||||
|
||||
// Consume the builder and bind a new [`Endpoint`].
|
||||
//
|
||||
// The returned `Endpoint` has no protocol handlers — use
|
||||
// [`Endpoint::bind`] with [`EndpointOptions::protocols`] to attach them.
|
||||
// The builder is single-use; a second `bind` returns
|
||||
// `EndpointBuilder already consumed`.
|
||||
func (_self *EndpointBuilder) Bind() (*Endpoint, error) {
|
||||
_pointer := _self.ffiObject.incrementPointer("*EndpointBuilder")
|
||||
defer _self.ffiObject.decrementPointer()
|
||||
res, err := uniffiRustCallAsync[*IrohError](
|
||||
FfiConverterIrohErrorINSTANCE,
|
||||
// completeFn
|
||||
func(handle C.uint64_t, status *C.RustCallStatus) C.uint64_t {
|
||||
res := C.ffi_iroh_ffi_rust_future_complete_u64(handle, status)
|
||||
return res
|
||||
},
|
||||
// liftFn
|
||||
func(ffi C.uint64_t) *Endpoint {
|
||||
return FfiConverterEndpointINSTANCE.Lift(ffi)
|
||||
},
|
||||
C.uniffi_iroh_ffi_fn_method_endpointbuilder_bind(
|
||||
_pointer),
|
||||
// pollFn
|
||||
func(handle C.uint64_t, continuation C.UniffiRustFutureContinuationCallback, data C.uint64_t) {
|
||||
C.ffi_iroh_ffi_rust_future_poll_u64(handle, continuation, data)
|
||||
},
|
||||
// freeFn
|
||||
func(handle C.uint64_t) {
|
||||
C.ffi_iroh_ffi_rust_future_free_u64(handle)
|
||||
},
|
||||
)
|
||||
|
||||
if err == nil {
|
||||
return res, nil
|
||||
}
|
||||
|
||||
return res, err
|
||||
}
|
||||
|
||||
// Set the address the endpoint binds to (`host:port`).
|
||||
func (_self *EndpointBuilder) BindAddr(addr string) error {
|
||||
_pointer := _self.ffiObject.incrementPointer("*EndpointBuilder")
|
||||
@@ -4886,6 +4986,14 @@ func (_ FfiDestroyerIncoming) Destroy(value *Incoming) {
|
||||
|
||||
// An Error.
|
||||
type IrohErrorInterface interface {
|
||||
// Detailed debug representation of the original Rust error.
|
||||
DebugMessage() string
|
||||
// Convenience helper for bindings that do not expose enum comparison
|
||||
// ergonomically.
|
||||
IsKind(kind IrohErrorKind) bool
|
||||
// Stable high-level error category.
|
||||
Kind() IrohErrorKind
|
||||
// Human-readable error message.
|
||||
Message() string
|
||||
}
|
||||
|
||||
@@ -4894,6 +5002,42 @@ type IrohError struct {
|
||||
ffiObject FfiObject
|
||||
}
|
||||
|
||||
// Detailed debug representation of the original Rust error.
|
||||
func (_self *IrohError) DebugMessage() string {
|
||||
_pointer := _self.ffiObject.incrementPointer("*IrohError")
|
||||
defer _self.ffiObject.decrementPointer()
|
||||
return FfiConverterStringINSTANCE.Lift(rustCall(func(_uniffiStatus *C.RustCallStatus) RustBufferI {
|
||||
return GoRustBuffer{
|
||||
inner: C.uniffi_iroh_ffi_fn_method_iroherror_debug_message(
|
||||
_pointer, _uniffiStatus),
|
||||
}
|
||||
}))
|
||||
}
|
||||
|
||||
// Convenience helper for bindings that do not expose enum comparison
|
||||
// ergonomically.
|
||||
func (_self *IrohError) IsKind(kind IrohErrorKind) bool {
|
||||
_pointer := _self.ffiObject.incrementPointer("*IrohError")
|
||||
defer _self.ffiObject.decrementPointer()
|
||||
return FfiConverterBoolINSTANCE.Lift(rustCall(func(_uniffiStatus *C.RustCallStatus) C.int8_t {
|
||||
return C.uniffi_iroh_ffi_fn_method_iroherror_is_kind(
|
||||
_pointer, FfiConverterIrohErrorKindINSTANCE.Lower(kind), _uniffiStatus)
|
||||
}))
|
||||
}
|
||||
|
||||
// Stable high-level error category.
|
||||
func (_self *IrohError) Kind() IrohErrorKind {
|
||||
_pointer := _self.ffiObject.incrementPointer("*IrohError")
|
||||
defer _self.ffiObject.decrementPointer()
|
||||
return FfiConverterIrohErrorKindINSTANCE.Lift(rustCall(func(_uniffiStatus *C.RustCallStatus) RustBufferI {
|
||||
return GoRustBuffer{
|
||||
inner: C.uniffi_iroh_ffi_fn_method_iroherror_kind(
|
||||
_pointer, _uniffiStatus),
|
||||
}
|
||||
}))
|
||||
}
|
||||
|
||||
// Human-readable error message.
|
||||
func (_self *IrohError) Message() string {
|
||||
_pointer := _self.ffiObject.incrementPointer("*IrohError")
|
||||
defer _self.ffiObject.decrementPointer()
|
||||
@@ -8601,6 +8745,73 @@ func (_ FfiDestroyerIncomingLocalAddr) Destroy(value IncomingLocalAddr) {
|
||||
value.Destroy()
|
||||
}
|
||||
|
||||
// Stable high-level error categories exposed across the FFI boundary.
|
||||
//
|
||||
// These are intentionally coarser than the upstream Rust error types. They
|
||||
// give foreign bindings a stable taxonomy for `errors.Is`-style handling
|
||||
// without leaking the internal `iroh` / `n0-error` error hierarchy.
|
||||
type IrohErrorKind uint
|
||||
|
||||
const (
|
||||
// Invalid input supplied by the caller.
|
||||
IrohErrorKindInvalidInput IrohErrorKind = 1
|
||||
// Failure while binding an endpoint.
|
||||
IrohErrorKindBind IrohErrorKind = 2
|
||||
// Failure while initiating or completing an outgoing connection.
|
||||
IrohErrorKindConnect IrohErrorKind = 3
|
||||
// An established connection failed or closed unexpectedly.
|
||||
IrohErrorKindConnection IrohErrorKind = 4
|
||||
// ALPN negotiation or lookup failed.
|
||||
IrohErrorKindAlpn IrohErrorKind = 5
|
||||
// Endpoint id / public key parsing failed.
|
||||
IrohErrorKindKeyParsing IrohErrorKind = 6
|
||||
// Ticket parsing failed.
|
||||
IrohErrorKindTicketParsing IrohErrorKind = 7
|
||||
// Relay configuration or relay operation failed.
|
||||
IrohErrorKindRelay IrohErrorKind = 8
|
||||
// Stream read/write/control operation failed.
|
||||
IrohErrorKindStream IrohErrorKind = 9
|
||||
// Datagram send/receive operation failed.
|
||||
IrohErrorKindDatagram IrohErrorKind = 10
|
||||
// Foreign callback failed.
|
||||
IrohErrorKindCallback IrohErrorKind = 11
|
||||
// Operation was attempted on a closed stream/connection/resource.
|
||||
IrohErrorKindClosed IrohErrorKind = 12
|
||||
// Operation timed out.
|
||||
IrohErrorKindTimeout IrohErrorKind = 13
|
||||
// Unclassified internal error.
|
||||
IrohErrorKindInternal IrohErrorKind = 14
|
||||
)
|
||||
|
||||
type FfiConverterIrohErrorKind struct{}
|
||||
|
||||
var FfiConverterIrohErrorKindINSTANCE = FfiConverterIrohErrorKind{}
|
||||
|
||||
func (c FfiConverterIrohErrorKind) Lift(rb RustBufferI) IrohErrorKind {
|
||||
return LiftFromRustBuffer[IrohErrorKind](c, rb)
|
||||
}
|
||||
|
||||
func (c FfiConverterIrohErrorKind) Lower(value IrohErrorKind) C.RustBuffer {
|
||||
return LowerIntoRustBuffer[IrohErrorKind](c, value)
|
||||
}
|
||||
|
||||
func (c FfiConverterIrohErrorKind) LowerExternal(value IrohErrorKind) ExternalCRustBuffer {
|
||||
return RustBufferFromC(LowerIntoRustBuffer[IrohErrorKind](c, value))
|
||||
}
|
||||
func (FfiConverterIrohErrorKind) Read(reader io.Reader) IrohErrorKind {
|
||||
id := readInt32(reader)
|
||||
return IrohErrorKind(id)
|
||||
}
|
||||
|
||||
func (FfiConverterIrohErrorKind) Write(writer io.Writer, value IrohErrorKind) {
|
||||
writeInt32(writer, int32(value))
|
||||
}
|
||||
|
||||
type FfiDestroyerIrohErrorKind struct{}
|
||||
|
||||
func (_ FfiDestroyerIrohErrorKind) Destroy(value IrohErrorKind) {
|
||||
}
|
||||
|
||||
// The logging level. See the rust (log crate)[https://docs.rs/log] for more information.
|
||||
type LogLevel uint
|
||||
|
||||
|
||||
+56
@@ -932,6 +932,12 @@ uint64_t uniffi_iroh_ffi_fn_clone_endpointbuilder(uint64_t handle, RustCallStatu
|
||||
#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_FFI_FN_FREE_ENDPOINTBUILDER
|
||||
#define UNIFFI_FFIDEF_UNIFFI_IROH_FFI_FN_FREE_ENDPOINTBUILDER
|
||||
void uniffi_iroh_ffi_fn_free_endpointbuilder(uint64_t handle, RustCallStatus *out_status
|
||||
);
|
||||
#endif
|
||||
#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_FFI_FN_CONSTRUCTOR_ENDPOINTBUILDER_NEW
|
||||
#define UNIFFI_FFIDEF_UNIFFI_IROH_FFI_FN_CONSTRUCTOR_ENDPOINTBUILDER_NEW
|
||||
uint64_t uniffi_iroh_ffi_fn_constructor_endpointbuilder_new(RustCallStatus *out_status
|
||||
|
||||
);
|
||||
#endif
|
||||
#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_FFI_FN_METHOD_ENDPOINTBUILDER_ALPNS
|
||||
@@ -954,6 +960,11 @@ void uniffi_iroh_ffi_fn_method_endpointbuilder_apply_n0(uint64_t ptr, RustCallSt
|
||||
void uniffi_iroh_ffi_fn_method_endpointbuilder_apply_n0_disable_relay(uint64_t ptr, RustCallStatus *out_status
|
||||
);
|
||||
#endif
|
||||
#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_FFI_FN_METHOD_ENDPOINTBUILDER_BIND
|
||||
#define UNIFFI_FFIDEF_UNIFFI_IROH_FFI_FN_METHOD_ENDPOINTBUILDER_BIND
|
||||
uint64_t uniffi_iroh_ffi_fn_method_endpointbuilder_bind(uint64_t ptr
|
||||
);
|
||||
#endif
|
||||
#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_FFI_FN_METHOD_ENDPOINTBUILDER_BIND_ADDR
|
||||
#define UNIFFI_FFIDEF_UNIFFI_IROH_FFI_FN_METHOD_ENDPOINTBUILDER_BIND_ADDR
|
||||
void uniffi_iroh_ffi_fn_method_endpointbuilder_bind_addr(uint64_t ptr, RustBuffer addr, RustCallStatus *out_status
|
||||
@@ -1139,6 +1150,21 @@ uint64_t uniffi_iroh_ffi_fn_clone_iroherror(uint64_t handle, RustCallStatus *out
|
||||
void uniffi_iroh_ffi_fn_free_iroherror(uint64_t handle, RustCallStatus *out_status
|
||||
);
|
||||
#endif
|
||||
#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_FFI_FN_METHOD_IROHERROR_DEBUG_MESSAGE
|
||||
#define UNIFFI_FFIDEF_UNIFFI_IROH_FFI_FN_METHOD_IROHERROR_DEBUG_MESSAGE
|
||||
RustBuffer uniffi_iroh_ffi_fn_method_iroherror_debug_message(uint64_t ptr, RustCallStatus *out_status
|
||||
);
|
||||
#endif
|
||||
#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_FFI_FN_METHOD_IROHERROR_IS_KIND
|
||||
#define UNIFFI_FFIDEF_UNIFFI_IROH_FFI_FN_METHOD_IROHERROR_IS_KIND
|
||||
int8_t uniffi_iroh_ffi_fn_method_iroherror_is_kind(uint64_t ptr, RustBuffer kind, RustCallStatus *out_status
|
||||
);
|
||||
#endif
|
||||
#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_FFI_FN_METHOD_IROHERROR_KIND
|
||||
#define UNIFFI_FFIDEF_UNIFFI_IROH_FFI_FN_METHOD_IROHERROR_KIND
|
||||
RustBuffer uniffi_iroh_ffi_fn_method_iroherror_kind(uint64_t ptr, RustCallStatus *out_status
|
||||
);
|
||||
#endif
|
||||
#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_FFI_FN_METHOD_IROHERROR_MESSAGE
|
||||
#define UNIFFI_FFIDEF_UNIFFI_IROH_FFI_FN_METHOD_IROHERROR_MESSAGE
|
||||
RustBuffer uniffi_iroh_ffi_fn_method_iroherror_message(uint64_t ptr, RustCallStatus *out_status
|
||||
@@ -2301,6 +2327,12 @@ uint16_t uniffi_iroh_ffi_checksum_method_endpointbuilder_apply_n0(void
|
||||
#define UNIFFI_FFIDEF_UNIFFI_IROH_FFI_CHECKSUM_METHOD_ENDPOINTBUILDER_APPLY_N0_DISABLE_RELAY
|
||||
uint16_t uniffi_iroh_ffi_checksum_method_endpointbuilder_apply_n0_disable_relay(void
|
||||
|
||||
);
|
||||
#endif
|
||||
#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_FFI_CHECKSUM_METHOD_ENDPOINTBUILDER_BIND
|
||||
#define UNIFFI_FFIDEF_UNIFFI_IROH_FFI_CHECKSUM_METHOD_ENDPOINTBUILDER_BIND
|
||||
uint16_t uniffi_iroh_ffi_checksum_method_endpointbuilder_bind(void
|
||||
|
||||
);
|
||||
#endif
|
||||
#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_FFI_CHECKSUM_METHOD_ENDPOINTBUILDER_BIND_ADDR
|
||||
@@ -2433,6 +2465,24 @@ uint16_t uniffi_iroh_ffi_checksum_method_sendstream_write(void
|
||||
#define UNIFFI_FFIDEF_UNIFFI_IROH_FFI_CHECKSUM_METHOD_SENDSTREAM_WRITE_ALL
|
||||
uint16_t uniffi_iroh_ffi_checksum_method_sendstream_write_all(void
|
||||
|
||||
);
|
||||
#endif
|
||||
#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_FFI_CHECKSUM_METHOD_IROHERROR_DEBUG_MESSAGE
|
||||
#define UNIFFI_FFIDEF_UNIFFI_IROH_FFI_CHECKSUM_METHOD_IROHERROR_DEBUG_MESSAGE
|
||||
uint16_t uniffi_iroh_ffi_checksum_method_iroherror_debug_message(void
|
||||
|
||||
);
|
||||
#endif
|
||||
#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_FFI_CHECKSUM_METHOD_IROHERROR_IS_KIND
|
||||
#define UNIFFI_FFIDEF_UNIFFI_IROH_FFI_CHECKSUM_METHOD_IROHERROR_IS_KIND
|
||||
uint16_t uniffi_iroh_ffi_checksum_method_iroherror_is_kind(void
|
||||
|
||||
);
|
||||
#endif
|
||||
#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_FFI_CHECKSUM_METHOD_IROHERROR_KIND
|
||||
#define UNIFFI_FFIDEF_UNIFFI_IROH_FFI_CHECKSUM_METHOD_IROHERROR_KIND
|
||||
uint16_t uniffi_iroh_ffi_checksum_method_iroherror_kind(void
|
||||
|
||||
);
|
||||
#endif
|
||||
#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_FFI_CHECKSUM_METHOD_IROHERROR_MESSAGE
|
||||
@@ -2625,6 +2675,12 @@ uint16_t uniffi_iroh_ffi_checksum_method_watchhandle_stop(void
|
||||
#define UNIFFI_FFIDEF_UNIFFI_IROH_FFI_CHECKSUM_CONSTRUCTOR_ENDPOINT_BIND
|
||||
uint16_t uniffi_iroh_ffi_checksum_constructor_endpoint_bind(void
|
||||
|
||||
);
|
||||
#endif
|
||||
#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_FFI_CHECKSUM_CONSTRUCTOR_ENDPOINTBUILDER_NEW
|
||||
#define UNIFFI_FFIDEF_UNIFFI_IROH_FFI_CHECKSUM_CONSTRUCTOR_ENDPOINTBUILDER_NEW
|
||||
uint16_t uniffi_iroh_ffi_checksum_constructor_endpointbuilder_new(void
|
||||
|
||||
);
|
||||
#endif
|
||||
#ifndef UNIFFI_FFIDEF_UNIFFI_IROH_FFI_CHECKSUM_CONSTRUCTOR_ENDPOINTID_FROM_BYTES
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
package iroh_ffi
|
||||
|
||||
// #cgo linux,amd64 LDFLAGS: -L${SRCDIR}/libs/x86_64-unknown-linux-musl -liroh -lm
|
||||
// #cgo linux,arm64 LDFLAGS: -L${SRCDIR}/libs/aarch64-unknown-linux-musl -liroh -lm
|
||||
import "C"
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,12 @@
|
||||
Copyright (c) 2026 iroh-go contributors
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
|
||||
this file except in compliance with the License. You may obtain a copy of the
|
||||
License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software distributed
|
||||
under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
specific language governing permissions and limitations under the License.
|
||||
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2026 iroh-go contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
+10
-6
@@ -9,8 +9,7 @@ RUST_FOLDER="$THIS_SCRIPT_DIR/../iroh-go"
|
||||
FFI_FOLDER="$THIS_SCRIPT_DIR/../iroh-ffi"
|
||||
GO_FOLDER="$THIS_SCRIPT_DIR/../"
|
||||
|
||||
# TARGETS="x86_64-unknown-linux-musl aarch64-unknown-linux-musl aarch64-apple-darwin x86_64-apple-darwin"
|
||||
TARGETS="x86_64-unknown-linux-musl"
|
||||
TARGETS="x86_64-unknown-linux-musl aarch64-unknown-linux-musl"
|
||||
|
||||
if ! command -v cross &> /dev/null; then
|
||||
echo "▸ cross tool not found, installing"
|
||||
@@ -21,7 +20,9 @@ if ! command -v rustup &> /dev/null; then
|
||||
echo "▸ rustup not found, please install it"
|
||||
exit 1
|
||||
else
|
||||
rustup target add $TARGETS
|
||||
for TARGET in $TARGETS; do
|
||||
rustup target add $TARGET
|
||||
done
|
||||
fi
|
||||
|
||||
export RUSTFLAGS="-C target-feature=+crt-static"
|
||||
@@ -32,11 +33,11 @@ for TARGET in $TARGETS; do
|
||||
cp "${RUST_FOLDER}/target/${TARGET}/release/${LIB_NAME}" "${GO_FOLDER}/libs/${TARGET}/${LIB_NAME}"
|
||||
done
|
||||
|
||||
TARGET="x86_64-unknown-linux-musl"
|
||||
echo "▸ Generate Go bindings"
|
||||
BINDGEN_TARGET="x86_64-unknown-linux-musl"
|
||||
echo "▸ generate Go bindings"
|
||||
cd "$RUST_FOLDER"
|
||||
uniffi-bindgen-go \
|
||||
"${GO_FOLDER}/libs/${TARGET}/${LIB_NAME}" \
|
||||
"${GO_FOLDER}/libs/${BINDGEN_TARGET}/${LIB_NAME}" \
|
||||
--library \
|
||||
--out-dir "${RUST_FOLDER}/target/go"
|
||||
|
||||
@@ -45,3 +46,6 @@ cp -r "${RUST_FOLDER}/target/go/iroh_ffi/iroh_ffi.go" "${GO_FOLDER}"
|
||||
|
||||
test -f "${RUST_FOLDER}/target/go/iroh_ffi/iroh_ffi.h"
|
||||
cp -r "${RUST_FOLDER}/target/go/iroh_ffi/iroh_ffi.h" "${GO_FOLDER}"
|
||||
|
||||
go -C "${GO_FOLDER}" fmt ./...
|
||||
go -C "${GO_FOLDER}" build -v iroh_ffi.go
|
||||
|
||||
Reference in New Issue
Block a user