/cointemplate

POST GET DELETE ASYNC

Manage the custom template image used for generating new coin files.

POST /api/v1/cointemplate
Alias: /upload-coin-template
GET /api/v1/cointemplate
Alias: /get-coin-template
DELETE /api/v1/cointemplate
Alias: /reset-coin-template

Description

This endpoint allows you to upload, retrieve, or delete a custom PNG image that serves as the background template for newly generated coin files (e.g., for `export` or `mint` operations).

Asynchronous Operation

All operations are asynchronous. They return a task ID immediately, and the final result must be retrieved by polling the /tasks/{id} endpoint.


POST /cointemplate (Upload)

Uploads a PNG file from the server's local file system to be used as the new coin template, overwriting any previous custom template.

Request Body

ParameterTypeRequiredDescription
pathstringYesThe absolute path to the PNG image file on the server's file system.

Response (in completed task `data`)

statusstring
Returns "success" if the operation completed.
messagestring
A confirmation message.

GET /cointemplate (Retrieve)

Retrieves the current custom coin template image, if one has been set.

Response (in completed task `data`)

Returns a JSON object containing the base64-encoded image data.

Example `data` in a Completed Task

{
    "data": "iVBORw0KGgoAAAANSUhEUgA...{very long base64 string}...kSuQmCC"
}

DELETE /cointemplate (Delete)

Deletes the current custom coin template file. The application will revert to its default template.

Response (in completed task `data`)

statusstring
Returns "success" if the operation completed.
messagestring
A confirmation message.

Examples

JavaScript: Generic Task Poller

const apiHost = 'http://localhost:8006';

// Generic function to poll any task
async function pollTask(taskId) {
    const taskResponse = await fetch(`${apiHost}/api/v1/tasks/${taskId}`);
    const taskData = await taskResponse.json();
    const task = taskData.payload;

    console.log(`Task ${taskId} progress: ${task.progress}% - ${task.message}`);

    if (task.status === 'completed') {
        console.log(`Task finished successfully!`, task.data);
        return true; // Stop polling
    } else if (task.status === 'error') {
        console.error(`Task failed:`, task.message);
        return true; // Stop polling
    }
    return false; // Continue polling
}

function startPolling(taskId) {
    const pollInterval = setInterval(async () => {
        const isDone = await pollTask(taskId);
        if (isDone) clearInterval(pollInterval);
    }, 2000); // Check every 2 seconds
}

JavaScript: Upload, Get, and Delete

async function uploadTemplate(serverPath) {
    const response = await fetch(`${apiHost}/api/v1/cointemplate`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ path: serverPath })
    });
    const taskInfo = await response.json();
    console.log(`Upload task created with ID: ${taskInfo.payload.id}`);
    startPolling(taskInfo.payload.id);
}

async function getTemplate() {
    const response = await fetch(`${apiHost}/api/v1/cointemplate`);
    const taskInfo = await response.json();
    console.log(`Get task created with ID: ${taskInfo.payload.id}`);
    startPolling(taskInfo.payload.id);
}

async function deleteTemplate() {
    const response = await fetch(`${apiHost}/api/v1/cointemplate`, { method: 'DELETE' });
    const taskInfo = await response.json();
    console.log(`Delete task created with ID: ${taskInfo.payload.id}`);
    startPolling(taskInfo.payload.id);
}

// Example usage:
// uploadTemplate('/path/on/server/my_template.png');
// getTemplate();
// deleteTemplate();

cURL: Upload Template

# Step 1: Initiate the upload task
TASK_ID=$(curl -s -X POST "http://localhost:8006/api/v1/cointemplate" \
-H "Content-Type: application/json" \
-d '{"path":"/path/on/server/my_template.png"}' | jq -r '.payload.id')
echo "Upload task started with ID: $TASK_ID"

# Step 2: Poll the task endpoint until finished
while true; do
  RESPONSE=$(curl -s "http://localhost:8006/api/v1/tasks/$TASK_ID")
  STATUS=$(echo $RESPONSE | jq -r '.payload.status')
  echo "Polling task.. Status: $STATUS"
  
  if [[ "$STATUS" == "completed" ]] || [[ "$STATUS" == "error" ]]; then
    echo "Final Response:"
    echo $RESPONSE | jq
    break
  fi
  sleep 2
done

cURL: Get Template

# Step 1: Initiate the get task
TASK_ID=$(curl -s -X GET "http://localhost:8006/api/v1/cointemplate" | jq -r '.payload.id')
echo "Get task started with ID: $TASK_ID"

# Step 2: Poll the task endpoint until finished
while true; do
  RESPONSE=$(curl -s "http://localhost:8006/api/v1/tasks/$TASK_ID")
  STATUS=$(echo $RESPONSE | jq -r '.payload.status')
  echo "Polling task.. Status: $STATUS"
  
  if [[ "$STATUS" == "completed" ]] || [[ "$STATUS" == "error" ]]; then
    echo "Final Response:"
    echo $RESPONSE | jq
    break
  fi
  sleep 2
done

cURL: Delete Template

# Step 1: Initiate the delete task
TASK_ID=$(curl -s -X DELETE "http://localhost:8006/api/v1/cointemplate" | jq -r '.payload.id')
echo "Delete task started with ID: $TASK_ID"

# Step 2: Poll the task endpoint until finished
while true; do
  RESPONSE=$(curl -s "http://localhost:8006/api/v1/tasks/$TASK_ID")
  STATUS=$(echo $RESPONSE | jq -r '.payload.status')
  echo "Polling task.. Status: $STATUS"
  
  if [[ "$STATUS" == "completed" ]] || [[ "$STATUS" == "error" ]]; then
    echo "Final Response:"
    echo $RESPONSE | jq
    break
  fi
  sleep 2
done

Go: Polling Logic and Main Functions

package main

import (
    "bytes"
    "encoding/json"
    "fmt"
    "log"
    "net/http"
    "time"
)

const apiHost = "http://localhost:8006/api/v1"

type TaskResponse struct {
    Payload struct {
        ID       string      `json:"id"`
        Status   string      `json:"status"`
        Progress int         `json:"progress"`
        Message  string      `json:"message"`
        Data     interface{} `json:"data"`
    } `json:"payload"`
}

// pollTask polls a task until it is complete or fails.
func pollTask(taskId string) {
    for {
        resp, err := http.Get(fmt.Sprintf("%s/tasks/%s", apiHost, taskId))
        if err != nil {
            log.Printf("Error polling task: %v\n", err)
            return
        }
        defer resp.Body.Close()

        var taskResp TaskResponse
        json.NewDecoder(resp.Body).Decode(&taskResp)

        fmt.Printf("Polling... Status: %s, Progress: %d%%\n", taskResp.Payload.Status, taskResp.Payload.Progress)

        if taskResp.Payload.Status == "completed" {
            fmt.Printf("Task completed successfully. Result: %+v\n", taskResp.Payload.Data)
            return
        } else if taskResp.Payload.Status == "error" {
            fmt.Printf("Task failed: %s\n", taskResp.Payload.Message)
            return
        }
        time.Sleep(2 * time.Second)
    }
}

Go: Upload, Get, and Delete Functions

func uploadTemplate(serverPath string) {
    payload, _ := json.Marshal(map[string]string{"path": serverPath})
    resp, err := http.Post(fmt.Sprintf("%s/cointemplate", apiHost), "application/json", bytes.NewBuffer(payload))
    if err != nil { log.Fatalf("Request failed: %v", err) }
    defer resp.Body.Close()
    
    var taskResp TaskResponse
    json.NewDecoder(resp.Body).Decode(&taskResp)
    fmt.Printf("Upload task created with ID: %s\n", taskResp.Payload.ID)
    pollTask(taskResp.Payload.ID)
}

func getTemplate() {
    resp, err := http.Get(fmt.Sprintf("%s/cointemplate", apiHost))
    if err != nil { log.Fatalf("Request failed: %v", err) }
    defer resp.Body.Close()

    var taskResp TaskResponse
    json.NewDecoder(resp.Body).Decode(&taskResp)
    fmt.Printf("Get task created with ID: %s\n", taskResp.Payload.ID)
    pollTask(taskResp.Payload.ID)
}

func deleteTemplate() {
    req, _ := http.NewRequest(http.MethodDelete, fmt.Sprintf("%s/cointemplate", apiHost), nil)
    resp, err := http.DefaultClient.Do(req)
    if err != nil { log.Fatalf("Request failed: %v", err) }
    defer resp.Body.Close()

    var taskResp TaskResponse
    json.NewDecoder(resp.Body).Decode(&taskResp)
    fmt.Printf("Delete task created with ID: %s\n", taskResp.Payload.ID)
    pollTask(taskResp.Payload.ID)
}