Findy Agency is an open-source project for a decentralized identity agency. OP Lab developed it from 2019 to 2024. The project is no longer maintained, but the work will continue with new goals and a new mission. Follow the blog for updates.
This is a Go wrapper for indy-sdk. It wraps most of the libindy's functions and data types, but it doesn't try to be complete. We have written it incrementally and wrapped only those functions that we need at the moment.
We haven't extended this wrapper with helper classes. It only tries to offer Go programming interface above the existing libindy API. findy-agent extends this wrapper with SSI/DID abstractions and offers more high-level API for SSI/DID development. For the most applications findy-agent is the one to start playing with.
This wrapper offers one key feature addition to that it's written in Go: it's not dependent on running indy ledger. The wrapper abstracts ledger with the plug-in interface which allows to implement any storage technology to handle needed persistence. Currently implemented ledger add-ons are:
- indy pool: data is saved into the indy ledger
- memory ledger: especially good for unit testing and caching
- file: data is saved into simple JSON file
- immudb: data is written to immutable database
Ubuntu 20.04< is preferred development environment but macOS is also an option. Please make sure that Go and git are both installed and working properly.
This is the preferred way to build and use Findy Go wrapper.
-
Install libindy-dev:
make indy_to_debian
Check indy-sdk installation instructions for more details.
-
Clone the repo:
git clone https://github.com/findy-network/findy-wrapper-go
-
Run the tests to see everything is working properly :
make test
Because indy SDK won't offer proper distribution for OSX, we have written a helper Bash script to perform installation. Follow these steps:
- Install Homebrew if it insn't already on your machine.
- Clone the repo:
git clone https://github.com/findy-network/findy-wrapper-go
- Go to directory
./scripts/mac-libindy
:$ cd scripts/mac-libindy
- Execute the installation script.
Or, if you want to change the default installation location, enter it as a first argument for the script.
$ ./install.sh
$ ./install.sh /my/own/location
- Follow the instructions of the
install.sh
i.e. source the env.sh which is generated to installation directory and is in your clipboard after successful installation.$ source /usr/local/opt/libindy/env.sh
- Run the tests to see everything is OK:
make test
The problem solving tip: source env.sh
in your dev session.
The findy-go package includes memory implementation of the ledger transaction
interface. If pool names are FINDY_MEM_LEDGER
or FINDY_ECHO_LEGDER
the
package uses its internal implementation of the ledger pool and lets you
perform all of its functions.
r := <-pool.OpenLedger("FINDY_MEM_LEDGER")
if r.Err() != nil {
return r.Err()
}
pool := r.Handle()
-
Create a ledger pool with indy CLI on VON Network or if
findy-agent
is installedfindy-agent ledger pool create --name <pool_name> --genesis-txn-file genesis.txt
To test ledger connection you can give the following command:
findy-agent ledger pool ping --name <pool_name>
-
Set environment variable:
export FINDY_POOL="FINDY_LEDGER,<pool_name>"
This will tell
anoncreds
tests to useFINDY_LEDGER
plugin that's the add-on for real Indy ledger. You give the pool name for the ledger after the comma. -
Run tests:
make test
.This will run all the pool tests towards the real ledger.
The wrapper includes minimal Go documentation. If you need more information about indy SDK, we suggest that you would read the original indy SDK documentation.
It follows the same sub-package structure as libindy. Also, function names are the same, but it respects Go idioms.
Original indy SDK function calls in C:
indy_key_for_did(...)
...
indy_key_for_local_did(..)
Same functions but with Go wrapper:
r := <-did.Key(pool, wallet, didStr)
...
r = <-did.LocalKey(wallet, didStr)
As you can see, the subjects that would exist in the function names aren't repeated if they are in the package names already.
The return type is Channel, which transfers dto.Result
Go structures. These
structures work similarly to C unions, which means that we can use one type for
all of the wrapper functions. To access the actual data, you have to know the
actual type. pool.OpenLedger()
returns Handle
type.
r = <-pool.OpenLedger("FINDY_MEM_LEDGER")
assert.NoError(r.Err())
h2 := r.Handle()
assert.Equal(h2, -1)
did.CreateAndStore()
returns two strings: did
and verkey
. Please note the
use of did.Did
struct instead of the JSON string.
r := <-did.CreateAndStore(w, did.Did{Seed: ""})
assert.NoError(r.Err())
did := r.Str1()
vk := r.Str2()
When a null string is needed for an argument, the predefined type must be used.
r = <-annoncreds.IssuerCreateAndStoreCredentialDef(w1, w1DID, scJSON,
"MY_FIRMS_CRED_DEF", findy.NullString, findy.NullString)
The Go error value can be retrieved with dto.Result.Err()
which returns Go
error
.