Creating portfolios is a two-step process with the Glider API:

  1. Generate a signature request that the user must sign with their wallet
  2. Submit the signed message to create the portfolio

Once created, you can configure the portfolio’s structure and settings.

Step 1: Generate a Signature Request

First, you need to request a signable message that will be used to create the portfolio:

const response = await fetch(
  "/v1/portfolio/create/signature",
  {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "X-API-KEY": API_KEY,
    },
    body: JSON.stringify({
      userAddress: "0xYourWalletAddress", // The wallet that will own the portfolio
      chainIds: [8453], // Chain IDs where the portfolio will exist (Base = 8453)
    }),
  }
);

const signatureData = await response.json();

The response will include a message that needs to be signed by the user’s wallet:

{
  "success": true,
  "data": {
    "userAddress": "0xYourWalletAddress",
    "chainIds": [8453],
    "accountIndex": 0,
    "kernelVersion": "0.3.2",
    "signatureAction": {
      "reason": "portfolio-permission",
      "type": "personal_sign",
      "message": "I authorize Glider to manage my portfolio\n\n0x8ad4d95c3c3d0a1e87bfdb1d2401905db4a97d8e05e77d69e5d79397da128b81"
    }
  },
  "correlationId": "corr_abcd1234",
  "requestId": "req_efgh5678",
  "timestamp": "2023-05-21T12:34:56.789Z"
}

Step 2: Sign the Message

Have the user sign the message using their wallet:

// Sign the message with the wallet (using viem, ethers, or other library)
const signature = await wallet.signMessage(signatureData.data.signatureAction.message);

Step 3: Submit the Signature to Create the Portfolio

Once you have the signature, submit it along with the original request data to create the portfolio:

const createResponse = await fetch(
  "/v1/portfolio/create",
  {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "X-API-KEY": API_KEY,
    },
    body: JSON.stringify({
      userAddress: signatureData.data.userAddress,
      chainIds: signatureData.data.chainIds,
      accountIndex: signatureData.data.accountIndex,
      kernelVersion: signatureData.data.kernelVersion,
      signatureAction: signatureData.data.signatureAction,
      signature: signature, // Add the signature from the user
    }),
  }
);

const portfolioResult = await createResponse.json();
const portfolioId = portfolioResult.data.portfolioId;

Step 4: Configure the Portfolio Template

After creating the portfolio, you need to configure its template with assets and settings:

const updateResponse = await fetch(
  `/v1/portfolio/${portfolioId}/update`,
  {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "X-API-KEY": API_KEY,
    },
    body: JSON.stringify({
      templateData: {
        name: "70/30 ETH-USDC Portfolio",
        description: "A simple portfolio with 70% ETH and 30% USDC allocation",
        entry: {
          blockType: "weight",
          weightType: "specified-percentage",
          weightings: ["70", "30"],
          children: [
            {
              blockType: "asset",
              assetId: "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE:8453" // ETH on Base
            },
            {
              blockType: "asset",
              assetId: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913:8453" // USDC on Base
            }
          ]
        },
        tradingSettings: {
          type: "threshold",
          triggerPercentage: 5
        }
      }
    }),
  }
);

const updatedPortfolio = await updateResponse.json();

Alternative: Create from Template

You can also create a portfolio directly from a template:

const createFromTemplateResponse = await fetch(
  "/v1/portfolios/create-from-template",
  {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "X-API-KEY": API_KEY,
    },
    body: JSON.stringify({
      templateId: "tmpl_xyz123", // The ID of the template to use
      userAddress: "0xYourWalletAddress", // The wallet that will own the portfolio
      chainIds: [8453], // Chain IDs where the portfolio will exist
      name: "My Custom Portfolio", // Optional custom name
      description: "Created from a template", // Optional custom description
    }),
  }
);

const templatePortfolioResult = await createFromTemplateResponse.json();
const templatePortfolioId = templatePortfolioResult.data.portfolioId;

Template Data Structure

The template data defines how your portfolio is structured:

  • name: The display name of the portfolio
  • description: A description of the portfolio
  • entry: The portfolio structure
    • blockType: The type of portfolio structure (e.g., “weight” for weighted allocation)
    • weightType: For weighted portfolios, specifies how weights are calculated (e.g., “specified-percentage”)
    • weightings: Array of string percentages for each asset
    • children: Array of assets or nested structures
      • For assets: { blockType: "asset", assetId: "0xTokenAddress:chainId" }
  • tradingSettings: Rebalancing settings
    • type: “threshold” or “calendar”
    • triggerPercentage: For threshold type, the deviation percentage that triggers rebalancing
    • frequency: For calendar type, how often to rebalance (e.g., “daily”, “weekly”, “monthly”)

Session Key Resignation

If a portfolio’s session keys need to be refreshed, you can resign the portfolio:

// Step 1: Get a new signature request for the existing portfolio
const resignResponse = await fetch(
  `/v1/portfolio/${portfolioId}/resign`,
  {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "X-API-KEY": API_KEY,
    },
    body: JSON.stringify({}), // No body required
  }
);

const resignData = await resignResponse.json();

// Step 2: Have the user sign the new message
const newSignature = await wallet.signMessage(resignData.data.signatureAction.message);

// Step 3: Submit the new signature
const resubmitResponse = await fetch(
  `/v1/portfolio/${portfolioId}/resubmit-signature`,
  {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "X-API-KEY": API_KEY,
    },
    body: JSON.stringify({
      signature: newSignature,
      signatureAction: resignData.data.signatureAction
    }),
  }
);

const resubmitResult = await resubmitResponse.json();

Next Steps

After creating a portfolio, you can:

  1. Deposit assets into the portfolio
  2. Start automation to enable automatic rebalancing
  3. Update the portfolio structure or settings as needed

For more detailed information about the available endpoints, see the Portfolio Management and Portfolio Creation API references.