Skip to Content

Stellar Integration

Individual Verifications on Stellar are recorded as SoulBound Tokens (SBTs) via Soroban smart contracts. This page covers everything you need to integrate Stellar-based verifications into your application.

Supported Verification Types

VerificationCircuit IDVerification URL
Government ID (KYC)0x729d660e1c02e4e419745e617d643f897a538673ccf1051e093bbfa58b0a120bid.human.tech/gov-id 
Phone0xbce052cf723dca06a21bd3cf838bc518931730fb3db7859fc9cc86f0d5483495id.human.tech/phone 

On EVM chains (Optimism, Base), attestations via Sign Protocol are the recommended integration. On Stellar, SBTs via Soroban are the current method.

SBT Contract

ComponentValue
Contract AddressCCNTHEVSWNDOQAMXXHFOLQIXWUINUPTJIM6AXFSKODNVXWA4N7XV3AI5
NetworkStellar Mainnet (Public)
RPC URLhttps://mainnet.sorobanrpc.com

Source code: GitHub 

Querying SBTs

Use the Stellar SDK to query a user’s SBT status off-chain:

import { rpc, TransactionBuilder, Networks, Contract, scValToNative, nativeToScVal, } from '@stellar/stellar-sdk' type StellarSbt = { action_nullifier: bigint circuit_id: bigint expiry: bigint id: bigint minter: string public_values: Array<bigint> recipient: string revoked: boolean } type StellarSbtStatus = 'valid' | 'expired' | 'revoked' | 'none' const sorobanRpcUrl = 'https://mainnet.sorobanrpc.com' const sbtContractAddress = 'CCNTHEVSWNDOQAMXXHFOLQIXWUINUPTJIM6AXFSKODNVXWA4N7XV3AI5' async function getStellarSBT( address: string, circuitId: string ): Promise<{ sbt?: StellarSbt; status: StellarSbtStatus }> { const sorobanServer = new rpc.Server(sorobanRpcUrl) const userAccount = await sorobanServer.getAccount(address) const contract = new Contract(sbtContractAddress) const operation = contract.call( 'get_sbt', nativeToScVal(address, { type: 'address' }), nativeToScVal(circuitId, { type: 'u256' }) ) const transaction = new TransactionBuilder(userAccount, { networkPassphrase: Networks.PUBLIC, fee: '100', }) .addOperation(operation) .setTimeout(60) .build() const response = await sorobanServer.simulateTransaction(transaction) if (rpc.Api.isSimulationSuccess(response)) { const parsed = rpc.parseRawSimulation(response) const sbt = scValToNative(parsed.result?.retval) return { sbt, status: 'valid' } } const error = response.error if (error?.includes('Error(Contract, #1)')) return { status: 'none' } if (error?.includes('Error(Contract, #5)')) return { status: 'revoked' } if (error?.includes('Error(Contract, #6)')) return { status: 'expired' } throw new Error(`SBT query failed: ${error}`) }

SBT Status Codes

StatusDescription
validSBT exists and is active
expiredSBT has passed its expiration date (1 year from issuance)
revokedSBT has been revoked
noneNo SBT found for this address

Circuit IDs

Use the appropriate circuit ID when querying SBTs for a specific verification type:

Verification TypeCircuit ID
Government ID (KYC)0x729d660e1c02e4e419745e617d643f897a538673ccf1051e093bbfa58b0a120b
Phone0xbce052cf723dca06a21bd3cf838bc518931730fb3db7859fc9cc86f0d5483495

Additional Resources

Last updated on