Skip to main content

services

The services/ packages provide the infrastructure adapters consumed by ABCI binaries and API servers. Each package defines an interface and one or more concrete implementations. Swap implementations by changing which concrete type is injected at startup — the ABCI state machines depend only on the interfaces.

Import root: github.com/NickCarducci/Shyware-SDK/services


services/identity

Defines IdentityVerifier — the interface the state machine uses to verify IDV attestations and derive identityHash.

type IdentityVerifier interface {
VerifyAndIdentify(data *tx.BallotCastData) (string, error)
VerifyAndIdentifyUpdate(data *tx.BallotUpdateData) (string, error)
VerifyAndIdentifyConfirm(data *tx.ConfirmReceiptData) (string, error)
}

Implementations

Typeidentity.providerNotes
DiditVerifierdiditBiometric IDV; enables keyless recovery
IdentusVerifieridentusDID wallet credential attestation
WalletVerifierwalletECDSA wallet-key commitment
NoopVerifiernoneDev/demo — skips verification, derives hash from pubkey
ZKVerifierdidit (ZK tier)Groth16 nullifier proof; commitment-blind

KYB extension

KYBVerifier handles entity (business) verification alongside participant identity:

type KYBVerifier interface {
VerifyEntity(req *EntityVerificationRequest) (*EntityRecord, error)
}

PersonaVerifier implements KYBVerifier for Persona-based business identity workflows.


services/kms

AWS KMS-backed signing for KMS period-close attestation.

type Signer struct { /* unexported */ }

func NewSigner(ctx context.Context, keyID string) (*Signer, error)
func (s *Signer) Sign(ctx context.Context, payload []byte) ([]byte, error)
func (s *Signer) PublicKeyDER() []byte
func (s *Signer) PublicKeyBase64() string
func (s *Signer) VerifyDER(payload, sigDER []byte) (bool, error)

NewSigner loads the public key from KMS at startup. Sign calls kms:Sign via the AWS SDK. The key never leaves KMS — signing happens inside the managed boundary. PublicKeyDER returns the verifying key for embedding in ClosureRecord.PublicKey.

Configure with signing.tally_key_id in the shyconfig (or SHYWARE_SIGNING_TALLY_KEY_ID / SIGNING_KEY_ID env vars).


services/signer

Defines the Signer interface consumed by the protocol state machine. services/kms.Signer implements it.

type Signer interface {
Sign(ctx context.Context, payload []byte) ([]byte, error)
}

Using the interface rather than the KMS concrete type allows local software signers in development and test without changing ABCI app code.


services/reconcile

Off-chain linkage store for the reconciling authority's per-participant receipt store. Four built-in implementations; implement Store directly for any other backend.

type Store interface {
RecordSubmission(ctx context.Context, pollID, identityHash, submissionID string) error
GetSubmissionID(ctx context.Context, pollID, identityHash string) (string, error)
RevealBallotEvidence(ctx context.Context, pollID, identityHash string) (string, error)
DeleteSubmission(ctx context.Context, pollID, identityHash string) error
}

// Any Postgres-compatible DB (CockroachDB, pg, RDS, Aurora, Supabase, Neon, PlanetScale Postgres)
func NewPostgresStore(db *sql.DB) *PostgresStore

// MySQL-compatible DB (MySQL, MariaDB, TiDB, Aurora MySQL, PlanetScale MySQL)
func NewMySQLStore(db *sql.DB) *MySQLStore

// AWS DynamoDB — for Lambda + DynamoDB stacks where a Postgres instance is out of place
func NewDynamoDBStore(ctx context.Context) (*DynamoDBStore, error)
func NewDynamoDBStoreWithClient(client *dynamodb.Client, table string) *DynamoDBStore

// MongoDB-compatible DB (MongoDB Atlas, DocumentDB, Cosmos DB MongoDB API, FerretDB, etc.)
func NewMongoStore(ctx context.Context, opts ...MongoOption) (*MongoStore, *mongo.Client, error)
func NewMongoStoreWithCollection(coll *mongo.Collection) *MongoStore

// Cloud Firestore — for GCP operators already using Firebase auth + GCP KMS
// Document IDs are SHA-256(pollID || identityHash): opaque, non-enumerable by poll
func NewFirestoreStore(ctx context.Context, opts ...FirestoreOption) (*FirestoreStore, error)
func NewFirestoreStoreWithClient(client *firestore.Client, collection string) *FirestoreStore

// In-process map — zero dependencies, for unit tests and local dev
var store reconcile.MemoryStore // zero value is ready to use

No implementation exposes a global scan primitive — GetSubmissionID and RevealBallotEvidence are per-participant and identity-gated. DeleteSubmission is called on TxTypeAuthorityRescind (count-match embodiments only). Pass DATABASE_URL to SQL-backed binaries; the driver (pgx vs go-sql-driver/mysql) determines which SQL store to instantiate. DynamoDB reads AWS_REGION + DYNAMODB_RECEIPT_TABLE. MongoDB reads MONGODB_URI + MONGODB_DB + MONGODB_RECEIPT_COLLECTION.

When --db-url is empty at startup, the API server runs in write-only posture — reconcile calls are no-ops and participants receive no off-chain receipt.


services/attest

Server-side device attestation verification for write-only posture enforcement.

type Verifier interface {
Verify(ctx context.Context, token string) (*VerifiedAttestation, error)
}

type VerifiedAttestation struct {
Platform string // "android" | "ios"
AppID string
Trusted bool
Reason string
}

Implementations

TypePlatformNotes
PlayIntegrityVerifierAndroidVerifies Google Play Integrity API tokens
NopVerifierDevAlways returns Trusted: true

PlayIntegrityVerifier is configured with PlayIntegrityConfig{PackageName, GoogleAppCredentials}. The API server calls Verify on each submission when deployment.runtime_fallbacks.write_only_on_missing_play_integrity: true — a failed or missing token triggers write-only posture for that submission.


services/telemetry

OpenTelemetry initialisation for all shyware server binaries.

func Init(ctx context.Context, serviceName string) (trace.TracerProvider, func(context.Context) error, error)
func Tracer(name string) trace.Tracer

Init sets up an OTLP trace exporter. The returned shutdown function flushes pending spans on graceful exit. Every ABCI binary and API server calls telemetry.Init at startup with its service name.

The service name appears as the service.name resource attribute in all traces — use it to filter spans in Grafana or the AWS X-Ray console. The SDK telemetry adapters (sdk/web/adapters/telemetry/) emit client-side spans that correlate with server-side traces via traceparent propagation.