Overview
Origins are authentication providers or entry points for identities in the Bloque platform. They represent organizations, blockchains, OAuth providers, or any system that can verify and register user identities.
What is an Origin?
An origin defines how users prove their identity when registering. Common origin types include:
EVM Blockchains - Ethereum, Polygon, Base (wallet signature verification)
OAuth Providers - Auth0, Google, etc.
OTP Providers - WhatsApp, Email (one-time password)
API Keys - Traditional API key authentication
Origin Structure
identity/src/internal/wire-types.ts
interface Origin {
namespace : string ; // Unique origin identifier
provider : 'evm' | 'auth0' | 'whatsapp' | 'email' | 'api-key' ;
status : 'active' | 'inactive' | 'disabled' ;
metadata : Record < string , unknown >;
created_at : string ;
updated_at : string ;
}
List Available Origins
Retrieve all registered origins:
const origins = await bloque . identity . origins . list ();
// Filter active origins
const activeOrigins = origins . filter ( o => o . status === 'active' );
// Find EVM origins
const evmOrigins = origins . filter ( o => o . provider === 'evm' );
console . log ( 'Available origins:' , origins . map ( o => o . namespace ));
Challenge Types
When registering an identity, users must complete a challenge to prove ownership. Bloque supports multiple challenge types:
Challenge Type Description Use Case SIGNING_CHALLENGECryptographic signature Blockchain wallets API_KEYAPI key authentication Backend services OAUTH_REDIRECTOAuth flow Social logins WEBAUTHNWebAuthn/Passkeys Passwordless auth OTPOne-time password Email/SMS/WhatsApp PASSWORDPassword authentication Traditional login
Registration Types
Bloque supports two types of identity registration:
Individual Registration (KYC)
For personal user accounts:
identity/src/origins/types.ts
interface IndividualRegisterParams {
assertionResult : AssertionResult ; // Challenge response
extraContext ?: Record < string , unknown >;
type : 'individual' ;
profile : UserProfile ;
}
interface UserProfile {
firstName ?: string ;
lastName ?: string ;
birthdate ?: string ; // ISO 8601 (YYYY-MM-DD)
email ?: string ;
phone ?: string ;
gender ?: string ;
addressLine1 ?: string ;
addressLine2 ?: string ;
city ?: string ;
state ?: string ;
postalCode ?: string ;
neighborhood ?: string ;
countryOfBirthCode ?: string ; // ISO country code
countryOfResidenceCode ?: string ;
personalIdType ?: string ; // e.g., 'SSN', 'passport'
personalIdNumber ?: string ;
}
Business Registration (KYB)
For business entities:
identity/src/origins/types.ts
interface BusinessRegisterParams {
assertionResult : AssertionResult ;
extraContext ?: Record < string , unknown >;
type : 'business' ;
profile : BusinessProfile ;
}
interface BusinessProfile {
// Required fields
legalName : string ; // Official legal name
name : string ; // Trading name/DBA
taxId : string ; // EIN, VAT, RFC, etc.
type : string ; // LLC, Corporation, etc.
incorporationDate : string ; // YYYY-MM-DD
addressLine1 : string ;
city : string ;
state : string ;
postalCode : string ;
country : string ;
// Optional fields
addressLine2 ?: string ;
countryCode ?: string ; // ISO country code
email ?: string ;
phone ?: string ;
logo ?: string ; // URL to logo image
// Owner information
ownerName ?: string ;
ownerIdType ?: string ;
ownerIdNumber ?: string ;
ownerAddressLine1 ?: string ;
ownerAddressLine2 ?: string ;
ownerCity ?: string ;
ownerState ?: string ;
ownerPostalCode ?: string ;
ownerCountryCode ?: string ;
}
Register Individual Identity
Example: Blockchain Wallet Registration
const registration = await bloque . identity . origins . register (
'[email protected] ' ,
'ethereum-mainnet' ,
{
assertionResult: {
alias: '0x742d35Cc6634C0532925a3b8D4C9db96C4b4d8b6' ,
challengeType: 'SIGNING_CHALLENGE' ,
value: {
signature: '0x1234567890abcdef...' ,
alias: '0x742d35Cc6634C0532925a3b8D4C9db96C4b4d8b6'
},
originalChallengeParams: {
challenge: 'bloque-challenge-1234567890' ,
timestamp: 1640995200
}
},
type: 'individual' ,
profile: {
firstName: 'John' ,
lastName: 'Doe' ,
email: '[email protected] ' ,
phone: '+1234567890' ,
birthdate: '1990-01-15' ,
city: 'New York' ,
state: 'NY' ,
postalCode: '10001' ,
addressLine1: '123 Main St' ,
countryOfBirthCode: 'USA' ,
countryOfResidenceCode: 'USA' ,
personalIdType: 'SSN' ,
personalIdNumber: '123-45-6789'
}
}
);
console . log ( 'Access token:' , registration . accessToken );
Example: Email OTP Registration
// 1. Request OTP challenge
const challenge = await bloque . identity . origins . email . assert ( '[email protected] ' );
console . log ( 'OTP sent to:' , challenge . value . email );
console . log ( 'Expires at:' , challenge . value . expires_at );
console . log ( 'Attempts remaining:' , challenge . params . attempts_remaining );
// 2. User enters OTP, then register
const registration = await bloque . identity . origins . register (
'[email protected] ' ,
'bloque-email' ,
{
assertionResult: {
alias: '[email protected] ' ,
challengeType: 'OTP' ,
value: {
signature: userEnteredOTP ,
alias: '[email protected] '
}
},
type: 'individual' ,
profile: {
firstName: 'Jane' ,
lastName: 'Smith' ,
email: '[email protected] ' ,
phone: '+1234567890'
}
}
);
Example: WhatsApp OTP Registration
// 1. Request WhatsApp OTP
const challenge = await bloque . identity . origins . whatsapp . assert ( '+1234567890' );
console . log ( 'OTP sent to:' , challenge . value . phone );
// 2. Register with OTP
const registration = await bloque . identity . origins . register (
'+1234567890' ,
'bloque-whatsapp' ,
{
assertionResult: {
alias: '+1234567890' ,
challengeType: 'OTP' ,
value: {
signature: userEnteredOTP ,
alias: '+1234567890'
}
},
type: 'individual' ,
profile: {
firstName: 'Carlos' ,
lastName: 'Garcia' ,
phone: '+1234567890'
}
}
);
Register Business Identity
const businessRegistration = await bloque . identity . origins . register (
'business-123' ,
'bloque-api' ,
{
assertionResult: {
alias: 'business-123' ,
challengeType: 'API_KEY' ,
value: {
apiKey: 'sk_live_abc123def456' ,
alias: 'business-123'
}
},
type: 'business' ,
profile: {
legalName: 'Acme Corporation' ,
name: 'Acme Corp' ,
taxId: '12-3456789' ,
type: 'LLC' ,
incorporationDate: '2020-01-15' ,
addressLine1: '123 Business St' ,
city: 'New York' ,
state: 'NY' ,
postalCode: '10001' ,
country: 'United States' ,
email: '[email protected] ' ,
phone: '+1-555-0123' ,
ownerName: 'Jane Smith' ,
ownerIdType: 'SSN' ,
ownerIdNumber: '123-45-6789'
}
}
);
console . log ( 'Business registered:' , businessRegistration . accessToken );
Custom Origins
Create a client for a custom origin:
const customOrigin = bloque . identity . origins . custom ( 'my-custom-origin' );
// Request assertion from custom origin
const assertion = await customOrigin . assert ( 'user-identifier' );
// Register using custom origin
const registration = await bloque . identity . origins . register (
'user-identifier' ,
'my-custom-origin' ,
registerParams
);
Registration Response
Successful registration returns an access token:
identity/src/origins/types.ts
interface RegisterResult {
accessToken : string ; // JWT access token for the registered identity
}
Use this token for authenticated API requests:
const { accessToken } = await bloque . identity . origins . register (
alias ,
origin ,
params
);
// Use token for authenticated requests
const authenticatedSDK = SDK . connect ({
accessToken: accessToken ,
environment: 'sandbox'
});
Built-in Origin Clients
Bloque provides pre-configured clients for common origins:
// Email OTP
const emailChallenge = await bloque . identity . origins . email . assert (
'[email protected] '
);
// WhatsApp OTP
const whatsappChallenge = await bloque . identity . origins . whatsapp . assert (
'+1234567890'
);
Best Practices
Select an origin that matches your authentication method:
Web3 apps: Use blockchain origins (EVM, Solana, etc.)
Traditional apps: Use email/WhatsApp OTP or OAuth
Backend services: Use API key authentication
Secure Challenge Handling
Never expose API keys in client-side code
Validate OTP codes server-side
Use HTTPS for all challenge requests
Implement rate limiting for OTP requests
Validate all profile fields before submission
Use ISO 8601 format for dates (YYYY-MM-DD)
Use ISO country codes for country fields
Normalize phone numbers to E.164 format
Store access tokens securely. Never commit them to version control or expose them in client-side code.
Compliance KYC verification after registration
Aliases Manage identity aliases