Skip to main content

Import

import {
  createWireClient,
  initializeFromShyConfig,
  assertWireManifest,
  WIRE_MANIFEST_CONTRACT_VERSION   // "shywire-v1"
} from 'shyware/sdk/web/wireClient.js'

Initialization

const client = await initializeFromShyConfig(shyconfig)
Requires contract_version: "shywire-v1" and a wire block with wrapper_mode, provider, provider_config, rematch_authority, and supported_networks.

Provider profile

const profile = client.getProviderProfile()
// → {
//     provider: "circle_usdc",
//     mode: "live",
//     intentPath: "/wire/intent",
//     settlementAsset: "USDC",
//     supportedRails: ["blockchain", "ach"],
//     requiresOperatorReview: false,
//     supportedNetworks: ["ethereum", "polygon"],
//     backingAsset: "USDC",
//     issuerName: "Oneway"
//   }

Asset and supply

await client.getAsset(assetId)
await client.getSupply(assetId)
// → { minted, burned, net }   — publicly auditable conservation
await client.getBalance(assetId, accountCommitment)
getSupply is public. Aggregate mint-minus-burn conservation is verifiable without the issuer’s cooperation or access to the linkage store.

Issue (deposit)

Issuing wraps an external stablecoin deposit into shywire anonymous-layer units.
const { txJson, intentId } = await client.buildIssueIntent({
  amount: 1000,
  destinationNetwork: 'ethereum',
  destinationAddress: '0xabc...',
  externalReference: 'deposit-ref-xyz'
})
// → TxType (intent) — dispatched to intentPath if configured

await client.createIssueIntent(args, { dispatch: true })
// build + POST to intentPath
After the issuer confirms the external deposit, the mint transaction is committed:
List 1: (assetId, amount, "mint") — no depositor identity
List 2: depositorCommitment       — no asset amount

Transfer

const { txJson, transferId, nullifier } = await client.buildTransfer({
  assetId: 'usdc-shywire',
  amount: 250,
  senderCommitment,
  recipientCommitment,
  memo: 'optional off-chain reference'
})
// → TxType 4
// transferId = H(randomNonce)        — direction-free public identifier
// nullifier  = H(senderCommit : assetId : nonce)

await client.submitTransfer(txJson)
// or
await client.transfer({ ... })   // combined
List 1: (assetId, amount, recipientHash) — no sender identity
List 2: senderCommitment               — no amount, no recipient
Neither record alone reveals the sender, amount, or counterparty. An observer sees that a transfer event occurred and the aggregate supply is unchanged; they cannot determine who sent what to whom.

Redeem (withdrawal)

const { txJson, intentId } = await client.buildRedeemIntent({
  amount: 500,
  accountCommitment,
  payoutRail: 'ach',
  payoutNetwork: 'us_ach',
  payoutDestination: 'routing:account'
})
// → dispatched to intentPath

await client.createRedeemIntent(args, { dispatch: true })
Validates that payoutRail is in supportedRails before building. The burn transaction committed on redemption:
List 1: (assetId, amount, "burn") — no redeemer identity
List 2: redeemerCommitment        — no amount

AML compliance and rematch authority

rematch_authority: "issuer_read_only" means the issuer can resolve a transferId to the originating senderCommitment through the protected linkage store. This is the OFAC and AML compliance path:
  • The issuer can satisfy sanctions screening and regulatory requests by querying the linkage store
  • The issuer cannot write to or alter canonical ledger state through this authority
  • Public ledger observers see only aggregate supply and direction-free transfer identifiers
  • A regulator with lawful process directed at the issuer obtains individual attribution; no linkage material is on-chain

Supported rails

payoutRailDescription
blockchainOn-chain transfer to a wallet address
achUS ACH bank transfer
wireDomestic or international wire transfer
Available rails are declared in wire.provider_config.supported_rails and validated at build time.