npm package: @stavbl/glide-sdk
Description: A powerful Node.js SDK for integrating with Glide's telecommunications and identity verification services.
Latest version: 2.2.0-alpha.3

# Glide SDK for Node.js

A powerful Node.js SDK for integrating with Glide's telecommunications and identity verification services.

## Features

- **Telco Finder**: Lookup carrier information by phone number or IP address
- **Magic Auth**: Authentication services including carrier-based phone verification
- **SIM Swap Detection**: Check for recent SIM card changes
- **Number Verification**: Verify phone numbers
- **KYC Match**: Know Your Customer verification services

## Installation

```bash
npm install @glide-sdk
```

## Configuration

First, create a `.env` file in the root directory with your Glide credentials:

```bash
GLIDE_CLIENT_ID=your-client-id
GLIDE_CLIENT_SECRET=your-client-secret
```

The SDK can be configured using environment variables or by passing settings directly to the client:

```typescript
import { GlideClient } from '@glide/sdk';

// Using environment variables
const client = new GlideClient();

// Or passing settings directly
const client = new GlideClient({
    clientId: 'your-client-id',
    clientSecret: 'your-client-secret',
    redirectUri: 'your-redirect-uri',
});
```

### Environment Variables

- `GLIDE_CLIENT_ID`: Your Glide client ID
- `GLIDE_CLIENT_SECRET`: Your Glide client secret
- `GLIDE_REDIRECT_URI`: OAuth redirect URI



## Usage Examples

### Telco Finder

```typescript
// Look up carrier information by phone number
const phoneResult = await client.telcoFinder.lookupNumber({
    phoneNumber: '+555123456789'
});
// Returns: { subject: 'tel:+555123456789', properties: { operatorId: 'Glide Test Lab' }, ... }

// Look up carrier information by IP address
const ipResult = await client.telcoFinder.lookupIp({
    ip: '80.58.0.0'
});
// Returns: { subject: 'ipport:80.58.0.0', properties: { operatorId: 'Movistar' }, ... }

// Get network ID for a phone number
const networkId = await client.telcoFinder.networkIdForNumber({
    phoneNumber: '+555123456789'
});
// Returns: { networkId: '6060' }
```

### Magic Auth

The Magic Auth service provides multiple authentication methods including traditional SMS/email flows and advanced carrier-based authentication using the Digital Credentials API.

#### Traditional Magic Auth Flow

```typescript
// Client-side Magic Auth
const magicAuthResult = await client.magicAuth.startAuth({
    phoneNumber: '+555123456789'
});
// Returns: { type: 'MAGIC', authUrl: 'https://...' }

// Verify the authentication
const verifyResult = await client.magicAuth.verifyAuth({
    phoneNumber: '+555123456789',
    token: 'token-from-auth-url'
});
// Returns: { verified: true }

// Server-side Magic Auth
const serverAuthResult = await client.magicAuth.startServerAuth({
    phoneNumber: '+555123456789',
    state: 'someState'
});
// Returns: { sessionId: '...', authUrl: 'https://...' }

// Check server auth status
const authStatus = await client.magicAuth.checkServerAuth(serverAuthResult.sessionId);
// Returns: { status: '...', verified: true/false }
```

#### Carrier-Based Phone Verification

The advanced carrier authentication flow uses the Digital Credentials API to securely verify phone numbers directly through carrier authentication without SMS. This provides a more seamless user experience and higher security.

##### Usage Flow

The carrier authentication involves three steps:
1. Call `prepare()` to check eligibility and get request data
2. Use the response in the browser's Digital Credentials API
3. Call `processCredential()` with the credential response

##### Step 1: Prepare Authentication

```typescript
// Using PLMN (Mobile Country Code + Mobile Network Code)
const prepareResponse = await client.magicAuth.prepare({
  plmn: {
    mcc: '310',  // Mobile Country Code
    mnc: '260'   // Mobile Network Code
  },
  use_case: 'GetPhoneNumber'
});

// Using phone number
const prepareResponse = await client.magicAuth.prepare({
  phone_number: '+14155552671',  // E.164 format
  use_case: 'VerifyPhoneNumber'
});

// With consent data
const prepareResponse = await client.magicAuth.prepare({
  phone_number: '+14155552671',
  use_case: 'GetPhoneNumber',
  consent_data: {
    consent_text: 'I agree to share my phone number',
    policy_link: 'https://example.com/privacy',
    policy_text: 'Privacy Policy'
  }
});
```

**Prepare Response Examples:**

If eligible:
```typescript
{
  protocol: 'openid4vp-v1-unsigned',
  data: {
    nonce: string,
    response_mode: 'dc_api',
    response_type: 'vp_token',
    dcql_query: {
      credentials: [...]
    }
  },
  session: {
    session_key: string,
    nonce: string,
    enc_key: string
  }
}
```

If not eligible:
```typescript
{
  eligible: false,
  carrier_name: 'Carrier Name',
  reason: 'Carrier not supported'
}
```

##### Step 2: Browser Digital Credentials API

Use the prepare response in your web client:

```javascript
// This code runs in the browser
if ('DigitalCredential' in window) {
  const credential = await navigator.credentials.get({
    digital: {
      provider: [prepareResponse]
    }
  });
  
  // Send credential to your backend
  const result = await fetch('/api/process-credential', {
    method: 'POST',
    body: JSON.stringify({
      credentialResponse: credential,
      session: prepareResponse.session
    })
  });
}
```

##### Step 3: Process Credential

Process the credential response on your backend:

```typescript
// Get phone number
const result = await client.magicAuth.processCredential({
  credentialResponse: credential,  // From Digital Credentials API
  session: prepareResponse.session, // From prepare() response
  options: {
    session_meta: {
      app_name: 'MyApp',
      terminal_vendor: 'Apple',
      terminal_model: 'iPhone'
    }
  }
});

// Verify phone number
const result = await client.magicAuth.processCredential({
  credentialResponse: credential,
  session: prepareResponse.session,
  phoneNumber: '+14155552671'  // Phone number to verify
});
```

**Process Credential Response Examples:**

Success response for GetPhoneNumber:
```typescript
{
  success: true,
  phone_number: '+14155552671',
  aud: 'audience-string'
}
```

Success response for VerifyPhoneNumber:
```typescript
{
  success: true,
  phone_number: '+14155552671',
  verified: true,
  aud: 'audience-string'
}
```

Error response:
```typescript
{
  success: false,
  error: 'Error message'
}
```

##### Use Cases

**GetPhoneNumber** - Retrieve the phone number associated with the device:

```typescript
// 1. Prepare
const prepareResponse = await client.magicAuth.prepare({
  plmn: { mcc: '310', mnc: '260' },
  use_case: 'GetPhoneNumber'
});

// 2. Browser gets credential (see browser code above)

// 3. Process
const result = await client.magicAuth.processCredential({
  credentialResponse,
  session: prepareResponse.session
});

console.log('Phone number:', result.phone_number);
```

**VerifyPhoneNumber** - Verify that the device has access to a specific phone number:

```typescript
const phoneToVerify = '+14155552671';

// 1. Prepare
const prepareResponse = await client.magicAuth.prepare({
  phone_number: phoneToVerify,
  use_case: 'VerifyPhoneNumber'
});

// 2. Browser gets credential (see browser code above)

// 3. Process
const result = await client.magicAuth.processCredential({
  credentialResponse,
  session: prepareResponse.session,
  phoneNumber: phoneToVerify
});

if (result.verified) {
  console.log('Phone number verified!');
}
```

##### Session Management

The SDK automatically manages carrier session state:

```typescript
// Get current session
const session = client.magicAuth.getMagicAuthSession();
if (session) {
  console.log('MCC:', session.mcc);
  console.log('MNC:', session.mnc);
  console.log('Expires at:', new Date(session.expiresAt));
}

// Manually set session (e.g., after restoring from storage)
client.magicAuth.setMagicAuthSession({
  mcc: '310',
  mnc: '260',
  expiresAt: Date.now() + (5 * 60 * 1000) // 5 minutes
});

// Clear session
client.magicAuth.clearMagicAuthSession();
```

##### Complete Express.js Example

```typescript
import express from 'express';
import { GlideClient } from '@glide/sdk';

const app = express();
app.use(express.json());

const client = new GlideClient({
  clientId: process.env.GLIDE_CLIENT_ID,
  clientSecret: process.env.GLIDE_CLIENT_SECRET
});

// Endpoint to prepare authentication
app.post('/api/magic-auth/prepare', async (req, res) => {
  try {
    const { phone_number, mcc, mnc, use_case } = req.body;
    
    const prepareResponse = await client.magicAuth.prepare({
      ...(phone_number ? { phone_number } : { plmn: { mcc, mnc } }),
      use_case
    });
    
    res.json(prepareResponse);
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

// Endpoint to process credential
app.post('/api/magic-auth/process', async (req, res) => {
  try {
    const { credentialResponse, session, phoneNumber } = req.body;
    
    const result = await client.magicAuth.processCredential({
      credentialResponse,
      session,
      phoneNumber
    });
    
    res.json(result);
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

app.listen(3000);
```

##### Important Notes

1. **Session Expiration**: The carrier session expires after 5 minutes
2. **Phone Number Format**: Always use E.164 format (+[country code][number])
3. **Use Case Validation**: When using `VerifyPhoneNumber`, a phone number must be provided
4. **Browser Compatibility**: Digital Credentials API is only available in supported browsers
5. **Security**: Always validate credentials on your backend, never trust client-side data

### SIM Swap Detection

```typescript
const simSwapClient = await client.simSwap.forUser({
    phoneNumber: '+555123456789'
});
const simSwapResult = await simSwapClient.check();
// Returns: { swapped: true/false }
```

### Number Verification

```typescript
// Get authentication URL
const authUrl = await client.numberVerify.getAuthUrl();

// Initialize verification for user with auth code
const verifyClient = await client.numberVerify.forUser({
    phoneNumber: '+555123456789',
    code: 'auth-code'
});

// Verify the number
const verificationResult = await verifyClient.verifyNumber();
// Returns: { devicePhoneNumberVerified: true/false }
```

### KYC Match

```typescript
const kycClient = await client.kycMatch.forUser({
    phoneNumber: '+555123456789'
});

const matchResult = await kycClient.match({
    phoneNumber: '+34629255833',
    idDocument: '66666666q',
    name: 'John Doe',
    givenName: 'John',
    familyName: 'Doe',
    birthdate: '1978-08-22',
    email: 'john@example.com',
    // Additional fields available...
});
// Returns match results for each field
```

## Error Handling

```typescript
try {
  const result = await client.magicAuth.prepare({
    phone_number: '+14155552671',
    use_case: 'GetPhoneNumber'
  });
} catch (error) {
  console.error('Prepare failed:', error.message);
}

try {
  const result = await client.magicAuth.processCredential({
    credentialResponse,
    session
  });
} catch (error) {
  console.error('Process failed:', error.message);
}
```

## TypeScript Support

This SDK is written in TypeScript and includes type definitions out of the box.

### Key Types

```typescript
interface AuthV2PrepDto {
  plmn?: {
    mcc: string;
    mnc: string;
  };
  phone_number?: string;
  use_case: 'GetPhoneNumber' | 'VerifyPhoneNumber';
  consent_data?: {
    consent_text: string;
    policy_link: string;
    policy_text: string;
  };
}

interface AuthV2ProcessCredentialDto {
  credentialResponse: DigitalCredentialResponse;
  session: SessionPayloadRaw;
  phoneNumber?: string;
  options?: {
    session_meta?: {
      terminal_id?: string;
      app?: string;
      app_name?: string;
      terminal_vendor?: string;
      terminal_model?: string;
      terminal_sw_version?: string;
      vers?: string;
      entitlement_version?: string;
      operation?: string;
      operation_targets?: string;
      eap_id?: string;
    };
  };
}