What it does
Accord records a group, an exact review request and the members who approve it. Use it to build a collective-review screen or rehearse an approval policy before a separate wallet/signing step.
The request binds the group digest, operation, attempt, message digest, policy digest, wallet and network. It does not treat a changed recipient, message or policy as the same approval. In the included local mode, reviewers are labels, not authenticated people: reaching the threshold still returns authorises: false and signs: false.
Use independently
Select uk.capp.sidecar.solana-accord and choose local-control for an offline rehearsal. No RPC, wallet, Circuit or Edge is required. Open the installed app's owning interface, window.capp.solana.accord, or use the portable client. A component existing in the Library is not the same as selecting it for this build.
Provider dependencies
| Mode | Required provider | What the application must do |
|---|---|---|
local-control | None | Label approvals as simulated and enforce any application review step separately. |
external-adapter | Your configured HTTPS authority service | Authenticate reviewers, enforce policy and verify the exact returned binding. Configuration alone does not qualify the service. |
Edge does not automatically call Accord merely because it is selected. A product that needs group review must integrate that decision explicitly before requesting wallet authority. Do not promote a local quorum into a real multisignature or threshold signature.
First successful review
- Choose distinct member IDs and a threshold no greater than the member count or configured limits. Create a group once and retain its ID and digest.
- Retain the business operation and attempt IDs. Compute the SHA-256 of the actual message bytes, not a display summary, for a real integration.
- Create the request with its exact binding. Supplying
messageBytesBase64enables the additional byte-to-digest comparison. - Collect approvals for that request. Read
quorum()and show the threshold, approval count and simulated/authentication flags together. - If any bound input changes, create a new request. Do not carry approvals across attempts or use the group ID alone as an approval token.
Rehearse two local reviewers
Copy the client module alongside your application's module and load it as a JavaScript module. This helper is inert until called. Invoke it only in a labelled test workspace with stable, application-chosen IDs. The text below is deliberately not a Solana transaction; automatically recording two labels demonstrates the simulator, not real user consent.
import {createSolanaClient} from './solana-client.mjs';
const client = createSolanaClient(() => window.capp?.solana);
export async function rehearseAccord({groupId, operationId}) {
const status = await client.call('accord', 'status');
if (!status.ready || status.providerMode !== 'local-control') {
throw new Error('Choose a ready local-control Accord rehearsal');
}
const group = await client.call('accord', 'createGroup', {
groupId, threshold: 2, members: ['reviewer-a', 'reviewer-b', 'reviewer-c']
});
const bytes = new TextEncoder().encode('Accord documentation rehearsal only');
const digest = new Uint8Array(await crypto.subtle.digest('SHA-256', bytes));
const messageDigest = [...digest].map(n => n.toString(16).padStart(2, '0')).join('');
const request = await client.call('accord', 'request', {
groupId: group.groupId, operationId, network: 'demo', messageDigest,
messageBytesBase64: btoa(String.fromCharCode(...bytes))
});
for (const memberId of ['reviewer-a', 'reviewer-b']) {
await client.call('accord', 'approve', {requestId: request.requestId, memberId});
}
const result = await client.call('accord', 'quorum', {requestId: request.requestId});
if (!result.simulated || result.authorises !== false || result.signs !== false) {
throw new Error('Unexpected authority result; do not use it as a rehearsal');
}
return result;
}For example, call rehearseAccord({groupId: 'docs-review-group', operationId: 'docs-review-1'}) from a Run rehearsal action. Expect two approvals, a reached quorum and no transaction signature. Repeating the exact call does not count either reviewer twice. Use a separate group ID when changing membership or threshold.
Scope and limitations
The included local reviewers are simulated identities. Two names on a request are not two cryptographic signatures. Member publicKey, commitment and attestationDigest fields are recorded metadata; their presence does not authenticate a member or validate a cryptographic attestation.
Local groups and requests are scoped to the application/origin and retained in local storage. They are not cross-device consensus. Capacity or storage errors stop new writes rather than silently discarding history. Treat exports as sensitive review metadata even though the API omits private keys and raw shares.
A saved request is immutable for its binding. On an idempotent replay, its original byte-presence flag is retained: adding message bytes later is not a way to upgrade an earlier digest-only review. Require byte binding when first creating a review that needs it.
Application API
The owning interface is window.capp.solana.accord. The portable client calls the same methods. This table describes main arguments, not a stricter typed guarantee than the current provider implements. Exact transaction/provider bindings must be preserved; unsupported state or arguments are rejected.
import {createSolanaClient} from './solana-client.mjs';
const client = createSolanaClient(() => window.capp?.solana);
const status = await client.call('accord', 'status');status
client.call('accord', 'status', input)
Main input: No arguments required.
Read collective-review provider readiness; local members remain unauthenticated labels.
createGroup
client.call('accord', 'createGroup', input)
Main input: members; optional groupId, threshold.
Create an immutable group with distinct member IDs. Changing membership requires a different group identity.
group
client.call('accord', 'group', input)
Main input: groupId.
Read the saved public group description.
request
client.call('accord', 'request', input)
Main input: groupId, operationId, messageDigest; optional requestId, attemptId, policyDigest, walletPubkey, network, messageBytesBase64.
Bind a review request to exact declared authority inputs. Supplied message bytes must match their digest.
approve
client.call('accord', 'approve', input)
Main input: requestId, memberId; optional attestationDigest.
Record one local member label against the saved request. It is not a cryptographic signature or authenticated vote.
quorum
client.call('accord', 'quorum', input)
Main input: requestId.
Read threshold and approval count. Local results explicitly do not authorize or sign a transaction.
Troubleshooting
| Symptom or error | Next step |
|---|---|
MEMBERS or a threshold error | Use distinct member IDs and a threshold within both the group size and configured limits. |
ID_CONFLICT | Recover the original group/request, or create a deliberately new identity for changed terms. |
MESSAGE_MISMATCH | Recompute from the same serialized bytes; do not hash the displayed description instead. |
MEMBER | The approval ID must be in the request's saved group. |
| Quorum reached but no signature | Expected in local-control mode. Use an authenticated signing provider for actual wallet authority. |
Verify your integration
Test exact request replay, duplicate approval, a non-member, changed message bytes and changed membership under an existing ID. Confirm that local quorum never starts a wallet call automatically. In external mode also test a mismatched response binding and an unavailable service; neither should fall back to local approval.
Integration recipes
Composition · Devnet payment · Recovery · Typed client · Schemas
Related data contracts
These schemas describe payload shape, not evidence of approval or successful execution. Match the version in your payload; older versions remain listed for compatibility.
Configuration reference
These are the selected package's configuration fields. String credential values and installation-specific defaults are never published here. A field's presence does not bypass its runtime policy.
| Field | Type | Meaning and constraints |
|---|---|---|
providerMode | select | Select the implementation this build will use. Configuring an endpoint does not verify its connection or behavior.. Choices: local-control, external-adapter |
defaultThreshold | number | Default M value for newly created M-of-N authority groups.. Bounds: 1 to 16 |
maxMembers | number | Upper bound on members accepted in a locally modelled authority group.. Bounds: 1 to 32 |
externalAdapterUrl | text | Absolute HTTPS endpoint, or loopback HTTP for development. Keep private credentials on the backend; packaged configuration is visible to users. |
Agent interfaces
These names are declared by the package for host/Agent integration, not JavaScript methods to invoke directly. The host must register a tool, grant its scope and enforce its approval policy. A manifest declaration alone does not prove availability in every Agent catalogue. Prefer the application API above when integrating your own app.
| Tool | Declared risk | Approval requirement |
|---|---|---|
solana.accord.status | low | mode-policy |