PHP code example of asciisd / pelican

1. Go to this page and download the library: Download asciisd/pelican library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

asciisd / pelican example snippets


use Asciisd\Copytrade\Facades\Copytrade;

// 1. Log in and get a token
$token = Copytrade::auth()->login('[email protected]', 'secret-password');

// 2. Scope the SDK to that token
$copytrade = Copytrade::withToken($token->accessToken);

// 3. Call the API through the domain services
$user       = $copytrade->profiles()->getUserInfo();
$profile    = $copytrade->profiles()->getProfile($user->profileId);
$copiers    = $copytrade->copiers()->getCopiers($user->profileId);
$strategies = $copytrade->strategies()->getStrategies($user->profileId);

use Asciisd\Copytrade\Facades\Copytrade;

$token = Copytrade::auth()->login('[email protected]', 'secret-password');

$token->accessToken;   // "eyJhbGciOi..." — use this for API calls
$token->refreshToken;  // used to renew the access token
$token->expiresIn;     // lifetime in seconds (e.g. 3600)
$token->expiresAt;     // CarbonImmutable expiry timestamp
$token->tokenType;     // "Bearer"

use Asciisd\Copytrade\Exceptions\AuthenticationException;

try {
    $token = Copytrade::auth()->login($email, $password);
} catch (AuthenticationException $e) {
    // e.g. "Login failed: invalid email or password."
    report($e);
}

use Asciisd\Copytrade\DTOs\Auth\TokenDTO;
use Illuminate\Support\Facades\Cache;

$token = Cache::get('copytrade_token')
    ? TokenDTO::fromArray(Cache::get('copytrade_token'))
    : null;

if ($token === null) {
    $token = Copytrade::auth()->login($email, $password);
} elseif ($token->isExpired(buffer: 60)) {
    $token = $token->canRefresh()
        ? Copytrade::auth()->refresh($token->refreshToken)
        : Copytrade::auth()->login($email, $password);
}

Cache::put('copytrade_token', $token->toArray(), $token->expiresAt);

Copytrade::auth()->revoke($token->accessToken);
Copytrade::auth()->revoke($token->refreshToken, 'refresh_token');

use Asciisd\Copytrade\Facades\Copytrade;

$authorization = Copytrade::auth()->authorizationRequest(
    redirectUri: 'https://your-app.example.com/copytrade/callback',
);

session([
    'copytrade_oauth_state' => $authorization->state,
    'copytrade_code_verifier' => $authorization->codeVerifier,
]);

return redirect()->away($authorization->authorizationUrl);

use Illuminate\Http\Request;

public function callback(Request $request)
{
    abort_unless(
        hash_equals(
            (string) $request->session()->pull('copytrade_oauth_state'),
            (string) $request->query('state'),
        ),
        403,
        'Invalid OAuth state.',
    );

    $token = Copytrade::auth()->exchangeCode(
        code: (string) $request->query('code'),
        codeVerifier: (string) $request->session()->pull('copytrade_code_verifier'),
        redirectUri: 'https://your-app.example.com/copytrade/callback',
    );

    $request->session()->put('copytrade_access_token', $token->accessToken);

    return redirect('/dashboard');
}

use Asciisd\Copytrade\Events\SsoAuthenticated;
use Asciisd\Copytrade\Events\SsoLoggedOut;
use App\Models\User;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Event;

Event::listen(SsoAuthenticated::class, function (SsoAuthenticated $event) {
    $user = User::query()->firstOrCreate(
        ['email' => $event->user->email],
        ['name' => $event->user->name ?? $event->user->email],
    );

    Auth::login($user);
});

Event::listen(SsoLoggedOut::class, function () {
    Auth::logout();
});

use Asciisd\Copytrade\Facades\Copytrade;

if (! Copytrade::sso()->isAuthenticated()) {
    return redirect()->route('copytrade.sso.redirect');
}

$token = Copytrade::sso()->token();          // refreshes automatically when expired
$user  = Copytrade::sso()->user();           // OpenID Connect claims + profile id

$copytrade = Copytrade::withToken($token->accessToken);
$profile   = $copytrade->profiles()->getProfile($user->profileId);

use Asciisd\Copytrade\Facades\Copytrade;
use Illuminate\Http\Request;

public function redirect()
{
    return redirect()->away(
        Copytrade::sso()->authorizationUrl(intendedUrl: '/dashboard')
    );
}

public function callback(Request $request)
{
    $session = Copytrade::sso()->handleCallback(
        (string) $request->query('code'),
        (string) $request->query('state'),
    );

    // $session->token and $session->user
    return redirect()->intended('/dashboard');
}

public function logout()
{
    return redirect()->away(
        Copytrade::sso()->logout(postLogoutRedirectUri: url('/'))
    );
}

$accountA = Copytrade::withToken($tokenA->accessToken);
$accountB = Copytrade::withToken($tokenB->accessToken);

$profileA = $accountA->profiles()->getProfile($profileIdA);
$profileB = $accountB->profiles()->getProfile($profileIdB);

// The user info response contains your profile ID
$user = Copytrade::withToken($accessToken)->profiles()->getUserInfo();

$profile = Copytrade::withToken($accessToken)->profiles()->getProfile($user->profileId);

$updated = Copytrade::withToken($accessToken)->profiles()->updateProfile($user->profileId, [
    'name' => 'New Name',          // optional, string
    'riskProfile' => 'Moderate',   // optional, string
    'countryCode' => 'EG',         // optional, ISO country code
]);

$servers = Copytrade::withToken($accessToken)->servers()->getServers();

$strategies = Copytrade::withToken($accessToken)->strategies();

// Create a strategy (a master account whose trades will be copied)
$strategy = $strategies->addStrategy($profileId, [
    'name' => 'My Trading Strategy',    // verCode' => 'XM-Real',      // es
$results = $strategies->searchStrategies('forex');
$stats = $strategies->getStrategyStats($strategy->id);

// Signal history
$open = $strategies->getStrategyOpenSignals($strategy->id);
$closed = $strategies->getStrategyClosedSignals($strategy->id, '2024-01-01', '2024-01-31');

// Images
$strategies->uploadStrategyImage($profileId, $strategy->id, file_get_contents($path), 'logo.png');
$thumbnailUrl = $strategies->getStrategyImageUrl($strategy->id); // public URL, no auth needed

// Remove the strategy from the profile
$strategies->removeStrategy($profileId, $strategy->id);

$copiers = Copytrade::withToken($accessToken)->copiers();

// Create a copier (a follower account that copies strategies)
$copier = $copiers->addCopier($profileId, [
    'name' => 'My Copier Account',      // gin)
        'password' => 'MyPassword',     // ng a strategy
$settings = $copiers->copyStrategy($copier->id, $strategyId, [
    'TradeSizeType' => 'Fixed',         // pToMinimumSize' => true,
]);
$copiers->stopCopying($copier->id, $strategyId);

// Monitor the copier
$stats = $copiers->getCopierStats($copier->id);
$copied = $copiers->getCopierStrategies($copier->id);
$open = $copiers->getCopierOpenSignals($copier->id);
$closed = $copiers->getCopierClosedSignals($copier->id, '2024-05-01', '2024-05-28');
$missed = $copiers->getMissedSignals($profileId, $copier->id);

$sections = Copytrade::withToken($accessToken)->sections()->getSections();

$spotlight = Copytrade::withToken($accessToken)->sections()->getSection('Spotlight');

$profile = Copytrade::withToken($accessToken)->profiles()->getProfile($profileId);

$profile->name;      // typed accessor
$profile->rawData;   // full raw API response
$profile->toArray(); // array representation

use Asciisd\Copytrade\Exceptions\AuthenticationException;
use Asciisd\Copytrade\Exceptions\CopytradeException;
use Asciisd\Copytrade\Exceptions\NotFoundException;

try {
    $profile = Copytrade::withToken($accessToken)->profiles()->getProfile($profileId);
} catch (AuthenticationException $e) {
    // Invalid or expired access token — re-login or refresh
} catch (NotFoundException $e) {
    abort(404, 'Profile not found');
} catch (CopytradeException $e) {
    Log::error('CopyTrade API error', ['message' => $e->getMessage()]);
}

use Asciisd\Copytrade\Contracts\ProfileServiceInterface;
use Asciisd\Copytrade\DTOs\Profile\ProfileDTO;

$this->mock(ProfileServiceInterface::class, function ($mock) {
    $mock->shouldReceive('getProfile')
        ->with('profile-123')
        ->andReturn(ProfileDTO::fromResponse([
            'id' => 'profile-123',
            'name' => 'Test User',
        ]));
});

use Illuminate\Support\Facades\Http;

Http::fake([
    'papi.copy-trade.io/api/servers' => Http::response([
        ['id' => 'srv-1', 'name' => 'Demo Server'],
    ]),
]);
bash
php artisan vendor:publish --tag=copytrade-config
blade
<a href="{{ route('copytrade.sso.redirect', ['intended' => '/dashboard']) }}">
    Continue with CopyTrade
</a>

<form method="POST" action="{{ route('copytrade.sso.logout') }}">
    @csrf
    <button type="submit">Sign out of CopyTrade</button>
</form>