opacity-issuer-sdk
v0.3.2
Published
Hosted Opacity integration client backed by mobile-api
Readme
opacity-issuer-sdk
Hosted external-frontend SDK for Opacity, backed by mobile-api. This package depends on opacity-issuer-core for shared protocol primitives.
import { createOpacityIssuerClient } from 'opacity-issuer-sdk';
const client = createOpacityIssuerClient({
issuerId: 'my-issuer',
environment: 'production',
apiBaseUrl: 'https://api.example.com',
chainId: 11155111,
headers: async () => ({ authorization: `Bearer ${await getToken()}` }),
walletClient,
});
const balances = await client.indexer.listBalances({ wallet });For a new issuer asset, discover infrastructure without copying contract addresses:
const { deployment, policies, evidence } = await client.issuers.discoverDeployment();
// Review the environment and approved policy candidates, then prepareDeployment with
// this deployment, your chosen policies and the new asset's own configuration.
// Send only on the user's explicit Deploy action and persist the transaction record.Version 0.3.x uses the configured backend's indexer and read-only RPC to verify factory deployment evidence and the registry's owner-selected policy infrastructure. No existing asset owned by the new issuer is required. The registry must have a contract platform operator exposing its policy engine, as in sandbox v3; unsupported wiring, stale data and ambiguous factories produce errors, not static-address fallbacks. Discovery does not upgrade an older live environment or grant issuer authorization. See the issuer lifecycle guide.
From 0.3.1, sandbox convenience calls also fail closed when backend registry discovery fails or
returns no registry; they never silently select a historical built-in address. Fix the discovery
error or deliberately provide a reviewed registry override. sandbox.deployment() remains an
explicit historical-reference lookup, not the current hosted deployment.
Hosted read-only RPC calls also handle temporary HTTP 429 rate limits with bounded retries.
Only explicitly allowed read methods qualify; transaction submission, wallet prompts and other
API mutations are never automatically repeated. Persistent rate limits still fail visibly.
There are at most three retries, with at most 60 seconds per delay and 120 seconds of total
backoff; Retry-After is respected within those bounds, and larger server-requested delays
surface the error instead of retrying early.
Without that header, delays are 20, 40 and 60 seconds. timeoutMs applies separately to each
network attempt; an abort cancels a pending backoff, and authentication is checked again before
each attempt.
For a frontend without Clerk, opt into verified wallet sessions on the same API:
const client = createOpacityIssuerClient({
issuerId: 'my-issuer',
environment: 'production',
apiBaseUrl: 'https://mobile-api.opacitylabs.com',
chainId: 11155111,
walletClient,
auth: { mode: 'wallet-session', wallet },
});
await client.walletSession!.signIn(); // Explicit user action; signs a one-time login message.
const balances = await client.indexer.listBalances({ wallet });
await client.walletSession!.signOut(); // Revokes this session and clears its local token.Apply the API's wallet-auth migrations and deploy the updated API. Wallet sessions are enabled
by default for https://mobile-api.opacitylabs.com, with no new required deployment environment
variables. WALLET_AUTH_ENABLED=false optionally disables wallet sessions; WALLET_AUTH_ORIGIN
overrides the API origin for custom/local deployments. Clerk continues to work through the
existing headers callback. Verified wallet sessions work under NODE_ENV=production; the legacy
auth.mode: 'wallet' bare-header mode remains development-only. The SDK checks the SIWE message
before signing, retains tokens
only in memory, and never automatically prompts or replays a failed mutation. Clear the session
on wallet/account/chain changes. extend() creates an independent client with no inherited
session. See the wallet authentication guide.
Indexed token/balance/transfer and vault history reads go through authenticated POST /indexer/:operation. Contract reads, simulation and receipt verification use POST /chains/:chain_id/rpc internally through the typed issuer, purchase and sandbox methods. Investor status and document acknowledgment, signing sessions and relay retain their mobile-api routes. Wallet signing and explicitly requested sends remain controlled by the caller.
Version 0.2.1 removes direct subgraphUrl, publicClient, and per-call sandbox reader configuration. Use opacity-issuer-core for issuer dashboards and applications that supply their own subgraph/RPC. Clerk/legacy document clients can omit chainId; verified wallet sessions and RPC operations need it. Sandbox uses its pinned chain default. The API must deploy the new authenticated indexer and read-only RPC routes before this SDK is used.
Pure protocol helpers, ABIs, types and document adapters remain exported. Direct issuer/purchase/subgraph factories are exported by core only. Backend configuration determines upstream endpoints; the frontend does not choose them.
With sandbox: true, client.sandbox.createUser({ transport, traits, funding: { amount }, persist })
generates a separate random test wallet, requests one approval for your exact funding amount, and
has the generated wallet automatically sign its own onboarding and trait transactions. persist receives
credentials before any transaction and progress around submissions; store this private data
securely. Supply a saved test privateKey to reuse that wallet and omit funding if already funded.
For browser sandbox fixtures, createSandboxUserStore({ chainId, registryAddress, namespace })
provides localStorage save/load/list, rename, export/import, and removal. Pass store.save directly
as persist; bigint progress is preserved and keys stay in this browser. Load a completed user
with store.load(wallet), check that the record exists, then call
restoreSandboxUserWallet(saved.progress, { chain, transport }) to get a local signer without
funding or sending. Reconcile pending creation before restoring.
There is no default amount and no automatic additional funding.
The write transport must support gas/fee estimation and locally signed transactions on the
configured chain. An arbitrary existing address without its key requires admin/TEE onboarding.
For a wallet you already manage, client.sandbox.prepareUser({ wallet, traits: { accredited: true,
jurisdictions: { US: true }, documents: { 'doc.mmf.subscription.v1': true } } }) returns only
needed onboarding and trait steps. Send each step.transaction from that test wallet through
client.issuers.sendTransaction, save its submission, and confirm with waitForTransaction
before continuing. Omitted traits stay unchanged; false clears a trait. Document traits do not
create signature records. See the sandbox user guide.
Transfers
Use client.transfers for live previews, one-transaction SecurityToken sends and verified receipts.
client.sandbox.transferUser uses a saved test wallet and can request one explicit sponsor gas
transfer before locally signing. See transfers and user switching.
