The TAC SDK provides flexible initialization options to support different development environments and use cases. This guide covers everything from basic setup to advanced configuration patterns.

Basic Initialization

Initialize the SDK using the static factory method with your target network:

import { TacSdk, Network } from "@tonappchain/sdk";

// Initialize for testnet development
const tacSdk = await TacSdk.create({
  network: Network.TESTNET,
});

// Initialize for production
const tacSdk = await TacSdk.create({
  network: Network.MAINNET,
});

Always use Network.TESTNET during development and testing. Switch to Network.MAINNET only when deploying to production.

Configuration Parameters

The TacSdk.create() method accepts a comprehensive configuration object:

const tacSdk = await TacSdk.create({
  network: Network.TESTNET,
  delay: 1000, // Delay between requests (milliseconds)
  TONParams: {
    // TON blockchain configuration
    contractOpener: tonClient, // Custom TonClient instance
    settingsAddress: "custom-settings-address",
  },
  TACParams: {
    // TAC blockchain configuration
    provider: customProvider, // Custom provider
    settingsAddress: "custom-settings-address",
  },
  customLiteSequencerEndpoints: [
    // Custom sequencer endpoints
    "https://custom-sequencer-1.com",
    "https://custom-sequencer-2.com",
  ],
});

Network Configuration

Testnet is the development environment with test tokens and contracts:

const tacSdk = await TacSdk.create({
  network: Network.TESTNET,
  delay: 1000  // Recommended for development
});

Testnet Features:

  • Free test tokens from faucets
  • Identical functionality to mainnet
  • Safe environment for experimentation
  • Faster confirmation times

Advanced Configuration

TON Parameters

Customize TON blockchain connection settings:

import { TonClient } from "@ton/ton";

const tonClient = new TonClient({
  endpoint: "https://testnet.toncenter.com/api/v2/jsonRPC",
  apiKey: process.env.TON_API_KEY, // For higher rate limits
});

const tacSdk = await TacSdk.create({
  network: Network.TESTNET,
  TONParams: {
    contractOpener: tonClient, // Custom TonClient instance
    settingsAddress: "custom-address", // Custom settings contract address
  },
});

Custom Sequencer Endpoints

Provide fallback sequencer endpoints for enhanced reliability:

const tacSdk = await TacSdk.create({
  network: Network.TESTNET,
  customLiteSequencerEndpoints: [
    "https://sequencer-1.tacchain.network",
    "https://sequencer-2.tacchain.network",
    "https://backup-sequencer.tacchain.network",
  ],
});

Environment-Specific Configuration

Development Environment

For local development and testing:

// .env.development
TAC_NETWORK = testnet;
TAC_DELAY = 1000;
TON_API_KEY = your - development - api - key;

// Application code
const tacSdk = await TacSdk.create({
  network:
    process.env.TAC_NETWORK === "mainnet" ? Network.MAINNET : Network.TESTNET,
  delay: parseInt(process.env.TAC_DELAY) || 1000,
  tonParams: {
    apiKey: process.env.TON_API_KEY,
  },
});

Production Environment

For production deployments:

// .env.production
TAC_NETWORK=mainnet
TAC_DELAY=500
TON_API_KEY=your-production-api-key
CUSTOM_SEQUENCER_1=https://sequencer-1.tacchain.network
CUSTOM_SEQUENCER_2=https://sequencer-2.tacchain.network

// Application code
const tacSdk = await TacSdk.create({
  network: Network.MAINNET,
  delay: 500,
  tonParams: {
    apiKey: process.env.TON_API_KEY
  },
  customLiteSequencerEndpoints: [
    process.env.CUSTOM_SEQUENCER_1,
    process.env.CUSTOM_SEQUENCER_2
  ]
});

Framework Integration Patterns

React Application

Create a context provider for SDK management:

import React, { createContext, useContext, useEffect, useState } from "react";
import { TacSdk, Network } from "@tonappchain/sdk";

const TacSdkContext = createContext(null);

export const TacSdkProvider = ({ children }) => {
  const [tacSdk, setTacSdk] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    const initializeSdk = async () => {
      try {
        setLoading(true);
        setError(null);

        const sdk = await TacSdk.create({
          network:
            process.env.NODE_ENV === "production"
              ? Network.MAINNET
              : Network.TESTNET,
          delay: process.env.NODE_ENV === "production" ? 500 : 1000,
          tonParams: {
            apiKey: process.env.REACT_APP_TON_API_KEY,
          },
        });

        setTacSdk(sdk);
      } catch (err) {
        console.error("Failed to initialize TAC SDK:", err);
        setError(err);
      } finally {
        setLoading(false);
      }
    };

    initializeSdk();

    // Cleanup on unmount
    return () => {
      if (tacSdk) {
        tacSdk.closeConnections();
      }
    };
  }, []);

  return (
    <TacSdkContext.Provider value={{ tacSdk, loading, error }}>
      {children}
    </TacSdkContext.Provider>
  );
};

export const useTacSdk = () => {
  const context = useContext(TacSdkContext);
  if (!context) {
    throw new Error("useTacSdk must be used within a TacSdkProvider");
  }
  return context;
};

Next.js Application

Handle client-side initialization with proper error boundaries:

// hooks/useTacSdk.js
import { useEffect, useState } from "react";
import { TacSdk, Network } from "@tonappchain/sdk";

export const useTacSdk = () => {
  const [tacSdk, setTacSdk] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    // Ensure client-side only
    if (typeof window === "undefined") return;

    const initializeSdk = async () => {
      try {
        const sdk = await TacSdk.create({
          network:
            process.env.NODE_ENV === "production"
              ? Network.MAINNET
              : Network.TESTNET,
          delay: process.env.NODE_ENV === "production" ? 500 : 1000,
        });

        setTacSdk(sdk);
        setError(null);
      } catch (err) {
        console.error("SDK initialization failed:", err);
        setError(err);
      } finally {
        setLoading(false);
      }
    };

    initializeSdk();

    return () => {
      if (tacSdk) {
        tacSdk.closeConnections();
      }
    };
  }, []);

  const reinitialize = async () => {
    setLoading(true);
    setError(null);

    try {
      if (tacSdk) {
        await tacSdk.closeConnections();
      }

      const sdk = await TacSdk.create({
        network: Network.TESTNET,
        delay: 1000,
      });

      setTacSdk(sdk);
    } catch (err) {
      setError(err);
    } finally {
      setLoading(false);
    }
  };

  return { tacSdk, loading, error, reinitialize };
};

Vue.js Application

Create a composable for SDK management:

// composables/useTacSdk.js
import { ref, onMounted, onUnmounted } from "vue";
import { TacSdk, Network } from "@tonappchain/sdk";

export function useTacSdk() {
  const tacSdk = ref(null);
  const loading = ref(true);
  const error = ref(null);

  const initialize = async () => {
    try {
      loading.value = true;
      error.value = null;

      tacSdk.value = await TacSdk.create({
        network: import.meta.env.PROD ? Network.MAINNET : Network.TESTNET,
        delay: import.meta.env.PROD ? 500 : 1000,
        tonParams: {
          apiKey: import.meta.env.VITE_TON_API_KEY,
        },
      });
    } catch (err) {
      console.error("TAC SDK initialization failed:", err);
      error.value = err;
    } finally {
      loading.value = false;
    }
  };

  onMounted(initialize);

  onUnmounted(() => {
    if (tacSdk.value) {
      tacSdk.value.closeConnections();
    }
  });

  return {
    tacSdk: readonly(tacSdk),
    loading: readonly(loading),
    error: readonly(error),
    reinitialize: initialize,
  };
}

SDK Properties and Methods

After initialization, the SDK instance provides several properties and methods:

Core Properties

const tacSdk = await TacSdk.create({ network: Network.TESTNET });

console.log(tacSdk.network); // Network.TESTNET
console.log(tacSdk.delay); // Configured delay in ms
console.log(tacSdk.artifacts); // Network-specific contract artifacts

Address Constants

// Native token addresses
console.log(tacSdk.nativeTONAddress); // "NONE" (represents native TON)
const tacAddress = await tacSdk.nativeTACAddress(); // TAC token address on EVM

Trusted Executors

// Get trusted executor addresses
const tacExecutors = tacSdk.getTrustedTACExecutors; // TAC chain executors
const tonExecutors = tacSdk.getTrustedTONExecutors; // TON chain executors

console.log("TAC Executors:", tacExecutors);
console.log("TON Executors:", tonExecutors);

Error Handling During Initialization

Handle initialization errors gracefully:

async function initializeSdkWithRetry(maxRetries = 3) {
  let lastError;

  for (let attempt = 1; attempt <= maxRetries; attempt++) {
    try {
      const tacSdk = await TacSdk.create({
        network: Network.TESTNET,
        delay: 1000 * attempt, // Increase delay on retries
      });

      console.log(`SDK initialized successfully on attempt ${attempt}`);
      return tacSdk;
    } catch (error) {
      console.warn(`Initialization attempt ${attempt} failed:`, error.message);
      lastError = error;

      if (attempt < maxRetries) {
        // Wait before retrying
        await new Promise((resolve) => setTimeout(resolve, 2000 * attempt));
      }
    }
  }

  throw new Error(
    `Failed to initialize SDK after ${maxRetries} attempts: ${lastError.message}`
  );
}

// Usage
try {
  const tacSdk = await initializeSdkWithRetry();
} catch (error) {
  console.error("SDK initialization failed permanently:", error);
  // Handle permanent failure (show error UI, etc.)
}

Lifecycle Management

Proper Cleanup

Always clean up SDK resources when your application shuts down:

// Single page applications
window.addEventListener("beforeunload", () => {
  if (tacSdk) {
    tacSdk.closeConnections();
  }
});

// React applications
useEffect(() => {
  return () => {
    if (tacSdk) {
      tacSdk.closeConnections();
    }
  };
}, [tacSdk]);

// Node.js applications
process.on("SIGINT", () => {
  if (tacSdk) {
    tacSdk.closeConnections();
  }
  process.exit(0);
});

Connection Management

The SDK manages multiple network connections internally. Monitor connection health:

async function checkSdkHealth(tacSdk) {
  try {
    // Test basic SDK functionality
    const nativeTacAddress = await tacSdk.nativeTACAddress();
    console.log("SDK health check passed:", nativeTacAddress);
    return true;
  } catch (error) {
    console.error("SDK health check failed:", error);
    return false;
  }
}

// Periodic health checks
setInterval(async () => {
  const isHealthy = await checkSdkHealth(tacSdk);
  if (!isHealthy) {
    // Reinitialize SDK or show connection error
  }
}, 30000); // Check every 30 seconds

Configuration Validation

Validate your configuration before initialization:

function validateSdkConfig(config) {
  // Network validation
  if (!Object.values(Network).includes(config.network)) {
    throw new Error(`Invalid network: ${config.network}`);
  }

  // Delay validation
  if (config.delay && (config.delay < 0 || config.delay > 10000)) {
    throw new Error(
      `Invalid delay: ${config.delay}. Must be between 0-10000ms`
    );
  }

  // TON params validation
  if (
    config.tonParams?.endpoint &&
    !config.tonParams.endpoint.startsWith("https://")
  ) {
    throw new Error("TON endpoint must use HTTPS");
  }

  // TAC params validation
  if (
    config.tacParams?.rpcUrl &&
    !config.tacParams.rpcUrl.startsWith("https://")
  ) {
    throw new Error("TAC RPC URL must use HTTPS");
  }

  return true;
}

// Usage
const config = {
  network: Network.TESTNET,
  delay: 1000,
  tonParams: {
    apiKey: process.env.TON_API_KEY,
  },
};

validateSdkConfig(config);
const tacSdk = await TacSdk.create(config);

What’s Next?

With the SDK properly initialized, you can proceed to wallet integration and cross-chain transactions:

Remember to always call tacSdk.closeConnections() when your application shuts down to properly clean up network resources and prevent memory leaks.