Framework Components

Dart

Integrate PichaFlow into your Dart applications and server-side environments.

The pichaflow_dart SDK is the core Dart client for the PichaFlow Engine. This package provides the foundational PichaFlowClient for communicating with the PichaFlow API, uploading assets, generating delivery URLs, and deleting media files.

Installation

Add pichaflow_dart to your pubspec.yaml:

dependencies:
  pichaflow_dart: ^0.1.0

Direct-to-Edge Uploads

If your environment is secure (e.g., server-side Dart, CLI tool, or test environment), you can initialize the client using your secret/API key directly:

import 'package:pichaflow_dart/pichaflow_dart.dart';

void main() async {
  final client = PichaFlowClient(
    PichaFlowConfig(
      apiKey: 'sk_live_your_secret_key',
    ),
  );

  final List<int> fileBytes = [/* raw image/file bytes */];

  try {
    final response = await client.upload(
      fileBytes,
      'avatar.jpg',
      options: UploadOptions(
        tags: ['user-avatar'],
      ),
    );
    print('Uploaded! ID: ${response.id}, URL: ${response.url}');
  } catch (e) {
    print('Failed: $e');
  }
}

Secure Handshake Uploads (HMAC Proxy)

When running inside client applications (like Flutter mobile or web apps), never expose your PichaFlow Secret Key (sk_live_...).

Instead, use the secure HMAC handshake flow:

  1. Provide a signatureUrl pointing to your backend signing endpoint.
  2. Call secureUpload(). The client fetches a temporary upload token from your signing backend and uploads the file directly to PichaFlow.
final client = PichaFlowClient(
  PichaFlowConfig(
    signatureUrl: 'https://your-api.com/v1/pichaflow-upload', // Signing endpoint
  ),
);

final response = await client.secureUpload(
  fileBytes,
  'photo.png',
  options: UploadOptions(directory: 'photos'),
);

!CAUTIONAuthentication Check Required: You must secure your backend signatureUrl endpoint with appropriate session or token authentication middleware. If this route is left public and unauthenticated, any user or bot can request valid signatures to upload files directly to your account, risking billing spikes or bucket abuse.

!NOTESignature Response Contract: Your signatureUrl endpoint must return a JSON body with the following fields. The component uses all of them to construct the five X-Picha-* headers sent to the Edge Engine:

{
  "signature":    "<hmac-sha256-hex>",
  "timestamp":    1234567890000,
  "tenantId":     "pf_prj_...",
  "directory":    "products/summer/",
  "maxSize":      "5242880",
  "allowedTypes": "image/webp,image/jpeg"
}

See HTTP API → Client-Side Upload Signatures for the full HMAC construction guide.

Implementing the Secure Signing Backend

Below is a complete Deno / Supabase Edge Function implementation for the signing endpoint:

import { serve } from "https://deno.land/std@0.168.0/http/server.ts"

const corsHeaders = {
  'Access-Control-Allow-Origin': '*',
  'Access-Control-Allow-Headers': 'authorization, x-client-info, apikey, content-type',
}

serve(async (req: Request) => {
  // CORS Preflight
  if (req.method === 'OPTIONS') {
    return new Response('ok', { headers: corsHeaders })
  }

  try {
    const pichaFlowKey = Deno.env.get('PICHAFLOW_SECRET_KEY')
    if (!pichaFlowKey) {
      throw new Error('Server configuration error: Missing PICHAFLOW_SECRET_KEY')
    }

    const body = await req.json().catch(() => ({}))

    // Call PichaFlow Management API to generate a signed upload token
    const response = await fetch('https://api.pichaflow.com/v1/upload/sign', {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${pichaFlowKey}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        tenantId: body?.tenantId,
        directory: body?.directory,
        maxSize: body?.maxSize,
        allowedTypes: body?.allowedTypes
      })
    })

    const data = await response.json()

    return new Response(JSON.stringify(data), {
      headers: { ...corsHeaders, 'Content-Type': 'application/json' },
      status: response.status
    })
  } catch (err: any) {
    return new Response(JSON.stringify({ error: err.message }), {
      headers: { ...corsHeaders, 'Content-Type': 'application/json' },
      status: 500
    })
  }
})

Delivery URLs

Generate optimized CDN URLs with presets and resize transformations:

final url = client.getDeliveryUrl(
  'users-photos/avatar.jpg',
  w: 300,
  h: 300,
  q: 85,
  f: 'webp',
);