> ## Content Index
> Fetch the complete content index at: https://stablecoininsider.org/llms.txt
> Use this file to discover other available public pages before exploring further.

# How to Send USDC with Solana Agent Kit (2026)
- URL: https://stablecoininsider.org/how-to-send-usdc-with-solana-agent-kit/
- Published: 2026-10-07T12:01:00.000Z
- Updated: 2026-10-07T12:27:21.000Z
- Description: Solana Agent Kit sends USDC in one call, but 2.4% of cent amounts throw and PYUSD fails. Here's the tested setup and a guarded PAY_USDC action.
- Author: Alexandra
- Tags: AI, Stablecoins

Solana Agent Kit can move USDC with one line of code. It can also fail on a 2.01 USDC payment, and it can't move PYUSD at all. Both facts come straight from its source code, and neither shows up in the quickstart.

This guide covers how to send USDC with **Solana Agent Kit**, SendAI's open-source toolkit that turns Solana actions into tools an AI model can call. You'll install the kit, pick a wallet, send a USDC transfer, expose it to a model or an MCP client, and then harden it with a guarded payment action. Along the way, Stablecoin Insider tested the transfer math on 100,000 amounts and checked four Solana stablecoin mints against the code path.

### Key Takeaways

- Solana Agent Kit sends USDC through the TokenPlugin transfer method and TRANSFER action.
- Amounts are UI units, multiplied by 10^decimals with plain JavaScript floats.
- In Stablecoin Insider's test, 2.38% of cent-level amounts threw a RangeError.
- Token-2022 stablecoins such as PYUSD and USDG fail the built-in transfer path.
- Ship a guarded custom action with an allowlist, a cap, and integer amounts.

🧭

What this guide is: an operator walkthrough of the USDC transfer path in Solana Agent Kit v2 (npm solana-agent-kit 2.0.10 and @solana-agent-kit/plugin-token 2.0.9), checked against the public v2 source and live Solana mainnet data on 7 October 2026.

## What Solana Agent Kit is, and which version you're installing

Solana Agent Kit is an Apache 2.0 licensed open-source toolkit from SendAI for [connecting any AI agent to Solana protocols](https://github.com/sendaifun/solana-agent-kit). Version 2 split the original monolith into a core package plus plugins, and the [V1 to V2 migration guide](https://github.com/sendaifun/solana-agent-kit/blob/v2/MIGRATING.md) says the private key is no longer required, because any wallet that implements the kit's wallet interface can sign.

Here's what that means for a USDC integration. You need only two packages: the core and the Token plugin. Everything else (NFT, DeFi, Misc, Blinks) is optional and adds tools your model can call, which is risk you may not want.

| Package                                                                                        | Latest on npm | Published   | What it gives a USDC flow                                       |
| ---------------------------------------------------------------------------------------------- | ------------- | ----------- | --------------------------------------------------------------- |
| [solana-agent-kit](https://www.npmjs.com/package/solana-agent-kit)                             | 2.0.10        | 24 Sep 2025 | SolanaAgentKit class, wallet interface, signOnly, tool adapters |
| [@solana-agent-kit/plugin-token](https://www.npmjs.com/package/@solana-agent-kit/plugin-token) | 2.0.9         | 24 Sep 2025 | transfer, balances, wallet address, Jupiter trade (26 actions)  |
| [@solana-agent-kit/adapter-mcp](https://www.npmjs.com/package/@solana-agent-kit/adapter-mcp)   | 2.0.7         | 24 Jul 2025 | startMcpServer for Claude Desktop and other MCP clients         |

Adoption is real but modest. The core package logged 5,435 npm downloads in the 30 days to 4 October 2026, per the [npm downloads API](https://api.npmjs.org/downloads/point/last-month/solana-agent-kit), against a peak of 11,483 in May 2026 in the [12-month download series](https://api.npmjs.org/downloads/range/2025-10-01:2026-09-30/solana-agent-kit). The repository shows 1,718 GitHub stars and a last commit on the v2 branch dated 14 May 2026 (UTC), per the [v2 commit history](https://github.com/sendaifun/solana-agent-kit/commits/v2).

That gap matters. Code on the v2 branch, such as an [owsWallet helper for Open Wallet Standard vaults](https://github.com/sendaifun/solana-agent-kit/blob/v2/packages/core/src/utils/owsWallet.ts), is not in the 2.0.10 tarball on npm. Stablecoin Insider checked the published bundle directly: it has signOnly and the tool adapters, but no owsWallet. Build against what npm ships, not what the README hints at.

## Step 1: Install the core and Token plugin

Install the two packages plus the Solana libraries the examples use. The kit is TypeScript-first and ships both ESM and CommonJS builds.

```
npm install solana-agent-kit @solana-agent-kit/plugin-token @solana/web3.js bs58
# only if you want an MCP server
npm install @solana-agent-kit/adapter-mcp
```

Then create the agent with a wallet, an RPC URL, and a config object. The config holds optional keys such as OPENAI\_API\_KEY and HELIUS\_API\_KEY, plus the signOnly flag covered in Step 2, per the [Config type](https://github.com/sendaifun/solana-agent-kit/blob/v2/packages/core/src/types/index.ts).

```
import { SolanaAgentKit, KeypairWallet } from "solana-agent-kit";
import TokenPlugin from "@solana-agent-kit/plugin-token";
import { Keypair } from "@solana/web3.js";
import bs58 from "bs58";

const keypair = Keypair.fromSecretKey(bs58.decode(process.env.AGENT_SECRET_KEY));
const wallet = new KeypairWallet(keypair, process.env.RPC_URL);

const agent = new SolanaAgentKit(wallet, process.env.RPC_URL, {
  HELIUS_API_KEY: process.env.HELIUS_API_KEY, // optional, for priority fee estimates
}).use(TokenPlugin);
```

## Step 2: Pick the wallet the agent signs with

The kit doesn't hold keys itself. It calls whatever object you pass that implements [BaseWallet](https://github.com/sendaifun/solana-agent-kit/blob/v2/packages/core/src/types/wallet.ts): a public key, signTransaction, signAllTransactions, signAndSendTransaction, and signMessage. That leaves three practical setups.

| Setup                          | How it signs                                                         | Best for                           | Watch out for                                |
| ------------------------------ | -------------------------------------------------------------------- | ---------------------------------- | -------------------------------------------- |
| KeypairWallet                  | Raw secret key in memory                                             | Devnet tests, internal bots        | Anyone with the env var can drain the wallet |
| Embedded or MPC wallet adapter | Provider signs (for example Privy or Turnkey) behind your own policy | Production agents with spend rules | You write the adapter methods yourself       |
| signOnly: true                 | Kit returns a signed transaction and never broadcasts                | Human approval, queues, co-signing | Your code must send and confirm it           |

The signOnly flag is the underused one. In [signOrSendTX](https://github.com/sendaifun/solana-agent-kit/blob/v2/packages/core/src/types/wallet.ts), the kit compiles and signs the transaction, then returns it instead of sending when signOnly is true. That gives you a clean checkpoint to log, review, or co-sign before a single cent moves.

If you're picking a managed signer, Stablecoin Insider has separate walkthroughs for [Privy agent wallets](https://stablecoininsider.org/how-to-provision-privy-agent-wallets-for-usdc/), [Turnkey agentic USDC payments](https://stablecoininsider.org/how-to-send-turnkey-agentic-usdc-payments/), and [Crossmint agent wallets](https://stablecoininsider.org/how-to-use-crossmint-agent-wallets-for-usdc/). The general setup lives in [how to set up an AI agent wallet](https://stablecoininsider.org/how-to-set-up-an-ai-agent-wallet/), and funding is covered in [how to fund an AI agent wallet with USDC](https://stablecoininsider.org/how-to-fund-ai-agent-wallet-with-usdc/).

## Step 3: Send USDC with the transfer method

The Token plugin exposes transfer(agent, to, amount, mint). Pass the amount in whole USDC, not base units, and pass the USDC mint. Mainnet USDC on Solana is EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v and Devnet USDC is 4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU, per [Circle's USDC contract addresses](https://developers.circle.com/stablecoins/usdc-contract-addresses).

```
import { PublicKey } from "@solana/web3.js";

const USDC = new PublicKey("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v");
const recipient = new PublicKey("RECIPIENT_WALLET_ADDRESS");

// 19.99 USDC, in UI units
const signature = await agent.methods.transfer(agent, recipient, 19.99, USDC);
console.log("sent", signature);
```

Under the hood, the [transfer tool](https://github.com/sendaifun/solana-agent-kit/blob/v2/packages/plugin-token/src/solana/tools/transfer.ts) does six things in order:

- Derives the sender's and recipient's associated token accounts for the mint.
- Creates the recipient's token account if it doesn't exist, with the agent wallet paying the rent deposit.
- Reads the mint to get decimals (6 for USDC).
- Multiplies your amount by 10 to the power of decimals.
- Builds a plain SPL Token transfer instruction (not transferChecked).
- Hands the instructions to signOrSendTX, which adds compute budget and priority fee instructions, then signs and sends.

The fee logic is worth knowing before an agent runs in a loop. Per [send\_tx.ts](https://github.com/sendaifun/solana-agent-kit/blob/v2/packages/core/src/utils/send%5Ftx.ts), the kit simulates the transaction, sets the compute limit to the larger of the estimate plus 100,000 units or 1.2 times the estimate (200,000 if simulation returns nothing), and prices it at the median of recent prioritization fees, or Helius's Medium estimate when HELIUS\_API\_KEY is set.

## Step 4: Expose the transfer to a model or an MCP client

The core package ships adapters for the Vercel AI SDK, LangChain, OpenAI, and Claude. Each one turns agent.actions into tools, and the [Vercel adapter](https://github.com/sendaifun/solana-agent-kit/blob/v2/packages/core/src/vercel-ai/index.ts) warns above 128 actions and slices the list to the first 127\. The Token plugin alone registers 26 actions in its [plugin index](https://github.com/sendaifun/solana-agent-kit/blob/v2/packages/plugin-token/src/index.ts), including TRANSFER, TRADE, and LAUNCH\_PUMPFUN\_TOKEN.

That's the first hardening step: don't hand the model all 26\. Filter to what the job needs.

```
import { createVercelAITools } from "solana-agent-kit";

const allowed = new Set(["WALLET_ADDRESS", "TOKEN_BALANCE_ACTION", "PAY_USDC"]);
const actions = agent.actions.filter((a) => allowed.has(a.name));
const tools = createVercelAITools(agent, actions);
```

For Claude Desktop or any MCP client, the [MCP adapter](https://github.com/sendaifun/solana-agent-kit/blob/v2/packages/adapter-mcp/src/index.ts) takes a map of actions and serves each one as a tool over stdio, plus an examples prompt for any action that ships examples. Pass the same short list.

```
import { startMcpServer } from "@solana-agent-kit/adapter-mcp";

const pick = (n) => agent.actions.find((a) => a.name === n);
startMcpServer(
  { WALLET_ADDRESS: pick("WALLET_ADDRESS"), TOKEN_BALANCE_ACTION: pick("TOKEN_BALANCE_ACTION"), PAY_USDC: payUsdc },
  agent,
  { name: "usdc-agent", version: "0.1.0" },
);
```

If your agent buys paid APIs instead of paying wallets, compare this with the HTTP-native route in [the x402 protocol explainer](https://stablecoininsider.org/x402-protocol/) and the [Cloudflare Agents x402 guide for paid MCP tools](https://stablecoininsider.org/how-to-charge-for-mcp-tools-with-cloudflare-agents-x402/). Coinbase's own stack is covered in [how to use Coinbase for Agents with MCP and CLI](https://stablecoininsider.org/how-to-use-coinbase-for-agents-with-mcp-and-cli/).

## Stablecoin Insider's test: the decimal bug in transfer

The [transfer tool](https://github.com/sendaifun/solana-agent-kit/blob/v2/packages/plugin-token/src/solana/tools/transfer.ts) computes the raw amount as amount \* Math.pow(10, decimals). JavaScript numbers are binary floats, so 2.01 \* 10^6 comes out as 2009999.9999999998\. The SPL Token library then converts that to a BigInt, which throws a [RangeError for non-integers](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Cant%5Fconvert%5Fx%5Fto%5FBigInt).

Stablecoin Insider ran every cent-level amount from 0.01 to 1,000.00 USDC (100,000 values) through that exact formula with @solana/spl-token 0.4.15, a version inside the range the kit's package.json allows. 2,384 of them, or 2.38%, produced a non-integer and failed in createTransferInstruction, matching the code in the [published transfer tool](https://github.com/sendaifun/solana-agent-kit/blob/v2/packages/plugin-token/src/solana/tools/transfer.ts).

| Amount the model asks for | amount \* 10^6 in JavaScript | Result            |
| ------------------------- | ---------------------------- | ----------------- |
| 2.01 USDC                 | 2009999.9999999998           | Throws RangeError |
| 4.03 USDC                 | 4030000.0000000005           | Throws RangeError |
| 0.000123 USDC             | 123.00000000000001           | Throws RangeError |
| 19.99 USDC                | 19990000                     | Sends             |
| 100 USDC                  | 100000000                    | Sends             |

Source: Stablecoin Insider test, 7 Oct 2026, against the formula in [transfer.ts](https://github.com/sendaifun/solana-agent-kit/blob/v2/packages/plugin-token/src/solana/tools/transfer.ts).

The failure is loud, not silent: the action throws "Transfer failed: The number ... cannot be converted to a BigInt" and nothing goes on chain. But an agent retrying with a tweaked amount, or a user wondering why a 2.01 USDC tip fails while 19.99 works, is exactly the kind of flaky behavior that kills trust in an agent product.

⚠️

Fix it at the boundary. Convert amounts to integer base units from a decimal string (split on the dot, pad to 6 places, BigInt the result) or round once with Math.round before the instruction is built. Never let a model-supplied float reach the token program.

## Which Solana stablecoins the built-in transfer can move

The transfer tool derives token accounts and reads the mint with the default SPL Token program. Stablecoins issued on [Token-2022](https://github.com/solana-program/token-2022) live under a different program, so getMint throws TokenInvalidAccountOwnerError before anything is signed. Stablecoin Insider read each mint from Solana mainnet on 7 October 2026 and reproduced that error for PYUSD.

| Stablecoin                                                                     | Mint program                                                        | Supply on Solana (7 Oct 2026) | Built-in transfer |
| ------------------------------------------------------------------------------ | ------------------------------------------------------------------- | ----------------------------- | ----------------- |
| [USDC](https://solscan.io/token/EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v)  | SPL Token                                                           | about 8.18 billion            | Works             |
| [USDT](https://solscan.io/token/Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB)  | SPL Token                                                           | about 3.84 billion            | Works             |
| [PYUSD](https://solscan.io/token/2b1kV6DkPAnxd5ixfnxCpjxmKwqjjaYmCZfHsFu24GXo) | Token-2022 (transfer hook, permanent delegate, transfer fee config) | about 708.38 million          | Fails at getMint  |
| [USDG](https://solscan.io/token/2u1tszSeqZ3qBWF3uNGPFc8TzMk2tdiwknnRMWGWjGWH)  | Token-2022 (same extension set)                                     | about 626.10 million          | Fails at getMint  |

Source: Solana mainnet getAccountInfo for each mint, linked to [Solscan](https://solscan.io/token/EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v); error reproduced with @solana/spl-token 0.4.15.

So the kit covers the two biggest dollar tokens on Solana, which is most of the volume. If your agent needs to pay in PYUSD or USDG, write your own instruction with the Token-2022 program ID and transferChecked, and test it against the mint's transfer hook. For the issuer side of USDG, see [how to mint and redeem USDG with Paxos](https://stablecoininsider.org/how-to-mint-and-redeem-usdg-with-paxos/), and for the wider field, [the top stablecoins on Solana](https://stablecoininsider.org/top-stablecoins-on-solana-in-june-2026/).

## Worked example: a guarded PAY\_USDC action

Say an operations agent pays approved contractors up to 250 USDC per transfer and 1,000 USDC per day. The built-in TRANSFER action accepts any address, any positive amount, and any mint, per its [zod schema](https://github.com/sendaifun/solana-agent-kit/blob/v2/packages/plugin-token/src/solana/actions/transfer.ts). So replace it with a custom action that enforces the rules in code, where a prompt injection can't talk its way past them.

```
import { z } from "zod";
import { PublicKey } from "@solana/web3.js";
import { getAssociatedTokenAddress, createTransferCheckedInstruction } from "@solana/spl-token";
import { signOrSendTX } from "solana-agent-kit";

const USDC = new PublicKey("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v");
const ALLOW = new Set(["CONTRACTOR_A_ADDRESS", "CONTRACTOR_B_ADDRESS"]);
const MAX_PER_TX = 250_000_000n;   // 250 USDC in base units
const MAX_PER_DAY = 1_000_000_000n; // 1,000 USDC
let spentToday = 0n;              // persist this in a database in production

const toBaseUnits = (s) => {
  const [whole, frac = ""] = s.split(".");
  if (frac.length > 6) throw new Error("max 6 decimals");
  return BigInt(whole) * 1_000_000n + BigInt(frac.padEnd(6, "0"));
};

export const payUsdc = {
  name: "PAY_USDC",
  similes: ["pay contractor in usdc", "send usdc payment"],
  description: "Pay an allowlisted contractor in USDC. Amount is a decimal string.",
  examples: [],
  schema: z.object({ to: z.string(), amount: z.string().regex(/^\d+(\.\d{1,6})?$/) }),
  handler: async (agent, { to, amount }) => {
    if (!ALLOW.has(to)) throw new Error("recipient not on allowlist");
    const raw = toBaseUnits(amount);
    if (raw > MAX_PER_TX || spentToday + raw > MAX_PER_DAY) throw new Error("limit exceeded");
    const owner = agent.wallet.publicKey;
    const from = await getAssociatedTokenAddress(USDC, owner);
    const dest = await getAssociatedTokenAddress(USDC, new PublicKey(to));
    const ix = createTransferCheckedInstruction(from, USDC, dest, owner, raw, 6);
    const signature = await signOrSendTX(agent, [ix]);
    spentToday += raw;
    return { status: "success", amount, to, signature };
  },
};
```

Run three requests through it. A request for 2.01 USDC to contractor A becomes exactly 2,010,000 base units and sends, where the float math in the [built-in transfer tool](https://github.com/sendaifun/solana-agent-kit/blob/v2/packages/plugin-token/src/solana/tools/transfer.ts) would throw. A request for 300 USDC fails the 250 USDC cap before any signing. A request to an address the model found in an email fails the allowlist. The design also requires the recipient's USDC account to exist already, which is a deliberate choice: allowlisted payees get onboarded once, so the agent never pays rent for strangers.

Combine this with signOnly for anything above a threshold, and you have a two-tier policy: small payments go out on their own, large ones wait for a person. The patterns behind those numbers are in [how to set spend limits on an AI agent USDC wallet](https://stablecoininsider.org/how-to-set-spend-limits-ai-agent-usdc-wallet/), and the kill switch is in [how to revoke AI agent USDC access](https://stablecoininsider.org/how-to-revoke-ai-agent-usdc-access/).

## Built-in TRANSFER vs a guarded custom action

| Attribute               | Built-in TRANSFER action                   | Guarded PAY\_USDC action            |
| ----------------------- | ------------------------------------------ | ----------------------------------- |
| Amount type             | JavaScript number in UI units              | Decimal string, converted to BigInt |
| Recipient check         | Any valid address string of 32+ characters | Allowlist in code                   |
| Limits                  | None                                       | Per-transfer and per-day caps       |
| Mint                    | Any mint the model passes, or SOL if none  | USDC only                           |
| Instruction             | transfer (no decimals check)               | transferChecked with 6 decimals     |
| Recipient token account | Created and paid for by the agent          | Must already exist                  |
| Token-2022 stablecoins  | Fail at getMint                            | Out of scope by design              |

Source: [TRANSFER action schema](https://github.com/sendaifun/solana-agent-kit/blob/v2/packages/plugin-token/src/solana/actions/transfer.ts) and [transfer tool](https://github.com/sendaifun/solana-agent-kit/blob/v2/packages/plugin-token/src/solana/tools/transfer.ts) on the v2 branch.

## Where Solana Agent Kit USDC payments break

- Float amounts. 2.38% of cent-level values threw before signing in testing.
- Token-2022 mints. PYUSD and USDG fail at getMint with the default program.
- Too many tools. Loading every plugin hands the model trading and token-launch tools it doesn't need.
- Raw keys in env vars. KeypairWallet is fine on Devnet and a liability on mainnet.
- No idempotency. A retried tool call can send twice, so key each payment and check before resending.
- Stale npm builds. Features on the v2 branch, such as owsWallet, aren't in 2.0.10.

Test every one of these on Devnet first. The checklist in [how to test an AI agent USDC payment before going live](https://stablecoininsider.org/how-to-test-ai-agent-usdc-payment-before-going-live/) applies here unchanged, and [how to reconcile AI agent USDC spend](https://stablecoininsider.org/how-to-reconcile-ai-agent-usdc-spend/) covers matching on-chain signatures back to the tool calls that caused them.

💡

Stablecoin Insider's take: Solana Agent Kit is the fastest way to give a model a Solana wallet, and for USDC and USDT the transfer path works. But it's a toolkit, not a payments product. The float math, the missing Token-2022 path, and an npm release that trails the repo by months all say the same thing: treat the built-in TRANSFER action as sample code. Teams paying real counterparties should write one guarded payment action, pair it with an MPC or embedded signer, and expose nothing else.

---

Shipping a Solana Agent Kit payment agent? Swap TRANSFER for a guarded action, run the 2.01 USDC case on Devnet, and confirm the signature lands before you give the model a mainnet wallet.

[Read the transfer tool source](https://github.com/sendaifun/solana-agent-kit/blob/v2/packages/plugin-token/src/solana/tools/transfer.ts)

Need a managed signer with policies behind your agent? Compare Turnkey's agentic USDC flow next.

[Send Turnkey Agentic USDC Payments ](https://stablecoininsider.org/how-to-send-turnkey-agentic-usdc-payments/) 

[Stablecoin Payments for AI AgentsHow AI agents pay and get paid in stablecoins, and which rails and wallets they use.![](https://stablecoininsider.org/favicon.ico)Stablecoin Insider](https://stablecoininsider.org/stablecoin-payments-for-ai-agents/)

Moving USDC onto Solana first? See [how to bridge USDC from Ethereum to Solana](https://stablecoininsider.org/how-to-bridge-usdc-from-ethereum-to-solana-step-by-step-2026/). If your agent swaps before it pays, the routing options are ranked in [the best DEX aggregators for stablecoin swaps](https://stablecoininsider.org/best-dex-aggregators-for-stablecoin-swaps-in-2026/).

## FAQ

#### What is Solana Agent Kit?

It's an open-source TypeScript toolkit from SendAI that turns Solana actions into tools an AI model can call. Version 2 uses a core package plus plugins such as the Token plugin.

#### How do you send USDC with Solana Agent Kit?

Load the Token plugin and call agent.methods.transfer(agent, recipient, amount, usdcMint) with the amount in whole USDC. The kit creates the recipient's token account if needed and sends the transaction.

#### Why does my Solana Agent Kit transfer fail with a BigInt error?

The kit multiplies a float amount by 10^6, and some values such as 2.01 come out as non-integers. Convert amounts to integer base units yourself, or round before the instruction is built.

#### Can Solana Agent Kit send PYUSD or USDG?

Not with the built-in transfer. Both are Token-2022 mints, and the tool reads mints with the default SPL Token program, so it fails before signing.

#### Do you need a private key to use Solana Agent Kit?

No. V2 accepts any wallet object that implements its signing interface, such as an embedded or MPC wallet adapter. KeypairWallet is there for raw keys.

#### Can Claude use Solana Agent Kit?

Yes. The MCP adapter's startMcpServer serves selected actions to Claude Desktop or another MCP client over stdio. The core also ships a createClaudeTools adapter.

#### How do you stop an AI agent from overspending USDC?

Don't expose the built-in TRANSFER action. Write a custom action with an allowlist and per-transfer and daily caps in code, and use signOnly for payments that need human approval.

---

This content is provided for informational and educational purposes only and does not constitute financial, investment, legal, or tax advice; no material herein should be interpreted as a recommendation, endorsement, or solicitation to buy or sell.