Quickstart
Prerequisites
- Node.js 18+ (web SDK)
- Go 1.22+ (runtime / ABCI node)
- Docker and Docker Compose (local node)
1. Start a local node
shyware-abci --config shyconfig.json --db-path /tmp/shyware-dev --addr :26658
shyware-api --config shyconfig.json --port 8080
Set identity.provider: "none" in your local shyconfig.json for development — the NoopVerifier skips IDV checks and derives a deterministic identity hash from the submitted public key.
For a full Docker Compose setup with CometBFT:
cd deploy/node/cometbft && docker compose up
2. Initialize a client
import { initializeFromShyConfig } from '@shyware/sdk/clients/voting'
const shyconfig = await fetch('/shyconfig.json').then(r => r.json())
const client = initializeFromShyConfig(shyconfig)
const summary = client.initialize()
// → { contractVersion: "shyvoting-v1", appId: "my-deployment", posture: "recoverable", ... }
3. Read submissions
const polls = await client.getAllSubmissions()
const poll = await client.getSubmission('polls', scopingId)
const tally = await client.getSubmissionTally('polls', scopingId)
const records = await client.getSubmissionRecords('polls', scopingId)
4. Cast a submission
const { submissionId, submissionNonce } = await client.voteSubmission({
scopingId: 'proposal-42',
payload: 'yes',
personId: 'didit-journey-id'
})
// submissionId — direction-free; publicly visible on-chain
// submissionNonce — private receipt; retain for post-close self-verification
The client derives identity_hash = H(identityCommitment || scopingId), generates submissionNonce, builds TxTypeBallotCast, POSTs to {api.base_url}/ballots, and persists the receipt to the configured store.
5. Verify the tally
const tally = await client.getSubmissionTally('polls', 'proposal-42')
// → { counts, totalVotes, confirmedCount, merkleRoot1, merkleRoot2, publicKey, signature }
Verify the KMS signature independently:
go run ShywareLLC/community/verify/cmd/verify --api http://localhost:8080 --poll proposal-42
# → Tally signature: VALID · Total: 42 · Confirmed: 39 / 42
6. Verify your own receipt
const records = await client.getSubmissionRecords('polls', 'proposal-42')
const verified = await client.verifyReceipt(submissionNonce, 'yes', records)
// → boolean — recomputes submissionId locally, no server contact
Other embodiments
// Weighted governance (shyshares)
import { initializeFromShyConfig } from '@shyware/sdk/clients/shares'
const client = initializeFromShyConfig(shyconfig)
await client.voteSubmission({ scopingId: proposalId, payload: 'yes', personId: commitment })
// Value transfer (shywire)
import { initializeFromShyConfig } from '@shyware/sdk/clients/wire'
const client = initializeFromShyConfig(shyconfig)
await client.wireSubmission({ scopingId: assetId, amount: 100, senderCommitment, recipientCommitment })
// Secret storage (shystore)
import { initializeFromShyConfig } from '@shyware/sdk/clients/store'
const client = initializeFromShyConfig(shyconfig, { getAuthHeaders, deriveSealerKey, signMessage })
await client.storeSubmission({ scopingId: bucketId, plaintext, category })
// Commodity custody (shycustody)
import { initializeFromShyConfig } from '@shyware/sdk/clients/custody'
const client = initializeFromShyConfig(shyconfig)
await client.buildRequestRedemption({ scopingId: assetId, amount: 5.0, redeemerCommitment })
// Revenue financing (shycontracts)
import { initializeFromShyConfig } from '@shyware/sdk/clients/contracts'
const client = initializeFromShyConfig(shyconfig)
await client.buildContractExecution({ contractId, partyCommitment, executionType: "remittance", sourceRef: "inv-001", amount: 12500 })
Next steps
- shyconfig manifest — full manifest reference
- Architecture — two-list state machine, identity tiers, count-match invariant
- Web SDK overview — uniform primitives, client module table
- ZK tier — high-assurance nullifier setup