SkillAtlasSkill 详情

dapp

A comprehensive AI skill for modern Stellar development with current best practices.

审核状态:已审核Quality 72Security 70

复制安装命令

用 Codex 或 Claude 安装复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它先审查 Skill 页面再帮你安装。

复制前请先查看来源、License 和安全提示。

项目 README

来源文件:README.md

抓取于 2026年9月14日

Stellar Development Skill

A comprehensive AI skill for modern Stellar development with current best practices. https://skills.stellar.org/

Inspired by solana-foundation/solana-dev-skill and cloudflare/skills.

[!NOTE] This skill was AI-generated using Claude Code and is currently under manual review. We welcome contributions! Please submit PRs, open issues, or provide feedback to help improve this resource for the Stellar ecosystem.

Overview

This skill provides AI assistants with deep knowledge of the current Stellar development ecosystem:

  • Smart Contracts: Stellar smart contracts (Rust soroban-sdk, WebAssembly)
  • Client SDKs: stellar-sdk (JavaScript), Python, Go, Rust
  • APIs: Stellar RPC (preferred), Horizon (legacy)
  • Assets: Stellar Assets, Stellar Asset Contract (SAC)
  • Wallets: Freighter, Stellar Wallets Kit, Smart Accounts (passkeys)
  • Testing: Local Quickstart, Testnet, Unit tests
  • Security: Smart contract security patterns, audit checklists
  • Ecosystem: DeFi protocols, developer tools, community projects

Raven: live MCP server

These skills give your agent durable Stellar context, baked in. Raven is a complementary remote Model Context Protocol (MCP) server for on-demand lookups: connect an agent and it searches Stellar docs and live ecosystem data, cross-referenced into single answers. Its catalog also includes these skills, so Raven is a live delivery gateway for them. Use both: skills for durable best practices, Raven for current lookups.

Raven is open source at kalepail/stellar-raven. Connect it in Claude Code:

claude mcp add --transport http stellar-raven "https://raven.stellar.buzz/mcp"

You can also try Raven in the browser at the playground, a hosted chat UI for asking Raven questions (sign-in required).

Installing

These skills work with any agent that supports the Agent Skills standard.

Claude Code

# Add this repo as a marketplace
/plugin marketplace add stellar/stellar-dev-skill

# Then install the skill
/plugin install stellar-dev@stellar-dev

OpenAI Codex

git clone https://github.com/stellar/stellar-dev-skill ~/.codex/skills/stellar-dev-skill

npx skills

npx skills add https://github.com/stellar/stellar-dev-skill

Clone / Copy

git clone https://github.com/stellar/stellar-dev-skill

Copy the skills/ directory contents to your assistant's skills location.

AgentSkill DirectoryDocs
Claude Code~/.claude/skills/docs
OpenCode~/.config/opencode/skill/docs
OpenAI Codex~/.codex/skills/docs
Pi~/.pi/agent/skills/docs

Skill Structure

skills/
├── smart-contracts/           # Stellar smart contracts — SKILL.md router + development/testing/security files
├── dapp/                      # Frontend — SKILL.md router + react / data-fetching / smart-accounts files
├── assets/SKILL.md            # Stellar Assets, trustlines, SAC bridge
├── data/                      # Stellar RPC (preferred) — SKILL.md router + horizon (legacy) file
├── agentic-payments/          # AI/machine payments — SKILL.md router + x402 / mpp files
├── zk-proofs/SKILL.md         # ZK verification (BLS12-381/BN254 Groth16, UltraHonk), Circom/Noir/RISC Zero
├── standards/                 # SEPs & CAPs — SKILL.md router + ecosystem / resources files
└── cross-chain/               # Cross-chain — SKILL.md router + cctp / axelar / layerzero files

Each sub-skill is a self-contained Agent Skill with its own frontmatter. Larger skills follow Anthropic's progressive-disclosure guidance: a sub-500-line SKILL.md router with a task-to-file table, plus companion files (one level deep) that load only when the task needs them. Cross-references link related skills (e.g., the agentic-payments skill points to smart-contracts for the SACs the protocols call, and to assets for USDC). The AI reads only the files relevant to the task at hand.

Example Prompts

"Help me write a Stellar smart contract for a token"
"Set up a Next.js app with Freighter wallet connection"
"How do I deploy a contract to Stellar Testnet?"
"Create unit tests for my smart contract"
"Review this contract for security issues"

Contributing

Contributions are welcome! Please ensure any updates reflect current Stellar ecosystem best practices.

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Submit a pull request

Guidelines

  • Keep information current (check stellar.org/developers for updates)
  • Focus on practical, actionable guidance
  • Include code examples where helpful
  • Cite official documentation when possible
  • Keep each SKILL.md body under ~500 lines — move deep dives into companion files routed by the task table
  • When a change touches what a skill teaches, update or add the matching scenario under evals/ in the same PR

Evaluations

evals/ holds ~3 task scenarios for each of the eight skills (plus cross-skill routing checks and a negative control), each encoding a mistake agents actually make without the skill. Three grading tiers: machine-checkable compile checks, LLM-judged behavior assertions, and skill-trigger checks. One gap is open: no baseline transcripts are committed, so the set is still unvalidated. See evals/README.md for the format, how to run them, and what the missing baselines mean.

Resources

License

Apache-2.0 License - see LICENSE for details.


Note: This repository is not in scope for the Stellar Development Foundation bug bounty program. Vulnerabilities found in this repo are not eligible for rewards.

开发与工程浏览器与自动化商业与运营

中风险

  • 来源需自行核对维护者身份。
  • 包含脚本或命令调用,安装前请复核。
  • 可能需要外部 token、网络权限或第三方服务。
  • 未检测到高风险命令。
  • 扫描发现:4 条。

Codex — Git Clone 安装

  1. 安装前请先查看来源仓库和风险报告。
  2. 克隆仓库:git clone https://github.com/stellar/stellar-dev-skill.git
  3. 将 "skills/dapp" 文件夹复制到 Codex 的 skills 目录中。
  4. 重启 Codex 让新的 skill 生效。

Codex — 手动复制安装

  1. 安装前请先查看来源仓库和风险报告。
  2. 从源仓库下载 SKILL.md 及相关文件。
  3. 在 Codex 的 skills 目录中创建新文件夹。
  4. 将所有 skill 文件复制到新文件夹中。
  5. 重启 Codex 让新的 skill 生效。

Claude Code — Git Clone 安装

  1. 安装前请先查看来源仓库和风险报告。
  2. 克隆仓库:git clone https://github.com/stellar/stellar-dev-skill.git
  3. 将 "skills/dapp" 文件夹复制到 Claude Code 的 skills 目录中。
  4. 重启 Claude Code 让新的 skill 生效。

Claude Code — 手动复制安装

  1. 安装前请先查看来源仓库和风险报告。
  2. 从源仓库下载 SKILL.md 及相关文件。
  3. 在 Claude Code 的 skills 目录中创建新文件夹。
  4. 将所有 skill 文件复制到新文件夹中。
  5. 重启 Claude Code 让新的 skill 生效。

Cursor — Git Clone 安装

  1. 安装前请先查看来源仓库和风险报告。
  2. 克隆仓库:git clone https://github.com/stellar/stellar-dev-skill.git
  3. 将 "skills/dapp" 文件夹复制到 Cursor 的 skills 目录中。
  4. 重启 Cursor 让新的 skill 生效。

Cursor — 手动复制安装

  1. 安装前请先查看来源仓库和风险报告。
  2. 从源仓库下载 SKILL.md 及相关文件。
  3. 在 Cursor 的 skills 目录中创建新文件夹。
  4. 将所有 skill 文件复制到新文件夹中。
  5. 重启 Cursor 让新的 skill 生效。

GitHub Copilot — Git Clone 安装

  1. 安装前请先查看来源仓库和风险报告。
  2. 克隆仓库:git clone https://github.com/stellar/stellar-dev-skill.git
  3. 将 "skills/dapp" 文件夹复制到 GitHub Copilot 的 skills 目录中。
  4. 重启 GitHub Copilot 让新的 skill 生效。

GitHub Copilot — 手动复制安装

  1. 安装前请先查看来源仓库和风险报告。
  2. 从源仓库下载 SKILL.md 及相关文件。
  3. 在 GitHub Copilot 的 skills 目录中创建新文件夹。
  4. 将所有 skill 文件复制到新文件夹中。
  5. 重启 GitHub Copilot 让新的 skill 生效。

Windsurf — Git Clone 安装

  1. 安装前请先查看来源仓库和风险报告。
  2. 克隆仓库:git clone https://github.com/stellar/stellar-dev-skill.git
  3. 将 "skills/dapp" 文件夹复制到 Windsurf 的 skills 目录中。
  4. 重启 Windsurf 让新的 skill 生效。

Windsurf — 手动复制安装

  1. 安装前请先查看来源仓库和风险报告。
  2. 从源仓库下载 SKILL.md 及相关文件。
  3. 在 Windsurf 的 skills 目录中创建新文件夹。
  4. 将所有 skill 文件复制到新文件夹中。
  5. 重启 Windsurf 让新的 skill 生效。
查看 SKILL.md 原文
name: dapp
description: Stellar dApp / frontend development. Covers the JavaScript stellar-sdk (browser + Node.js), Freighter wallet, Stellar Wallets Kit (multi-wallet), Wallet Standard, smart accounts with passkeys, transaction building / signing / submission, smart contract invocation from the client, simulation, and error handling. Use when building a React/Next.js/Node.js app that talks to Stellar — classic operations or smart contracts.
user-invocable: true
argument-hint: "[dapp task]"

Stellar dApp / Frontend

Client-side development with @stellar/stellar-sdk, wallet connection, signing, and submitting transactions. Covers both classic Stellar operations and smart contract invocation from the browser or Node.js.

When to use this skill

  • Connecting Freighter or other wallets via Stellar Wallets Kit
  • Building, simulating, signing, and submitting transactions
  • Invoking Stellar smart contracts from a frontend
  • Implementing smart accounts with passkeys
  • Handling network passphrases (Mainnet / Testnet / local)

Related skills

  • Writing the contract being invoked → ../smart-contracts/SKILL.md
  • Issuing assets and managing trustlines → ../assets/SKILL.md
  • Querying chain state via RPC / Horizon → ../data/SKILL.md
  • Building paid APIs or agent payment clients → ../agentic-payments/SKILL.md
  • SEPs the wallet/anchor flows depend on → ../standards/SKILL.md

Goals

  • Single SDK instance for the app (RPC/Horizon + transaction building)
  • Freighter wallet integration (or multi-wallet via Stellar Wallets Kit)
  • Clean separation of client/server in Next.js
  • Transaction sending with proper confirmation handling

Read the file that matches the task

This file covers SDK setup, wallet connection, and transaction build/sign/submit. The deep dives live alongside it:

TaskFile
SDK setup and env configSDK Initialization (below)
Wallet integrations (Freighter, Wallets Kit)Wallet Integration (below)
Tx build/send patternsTransaction Building, Transaction Submission (below)
Connect-wallet button, payment form, Next.js App Router wiringreact.md
Account balances, contract reads (queryContract), raw ledger entriesdata-fetching.md
Passkey smart wallets (Smart Account Kit), gasless tx via OpenZeppelin Relayersmart-accounts.md
Production UX checklistTransaction UX Checklist (below)

Recommended Dependencies

Requires Node.js 22+. As of SDK v16, Node 22 is the minimum (older Node produces an EBADENGINE warning). v16 also folded @stellar/stellar-base into @stellar/stellar-sdk, is ESM-first, and uses native fetch instead of axios. If you still import @stellar/stellar-base directly, switch the import to @stellar/stellar-sdk and uninstall the base package (keeping both breaks instanceof checks). See the migration guide.

npm install @stellar/stellar-sdk @stellar/freighter-api
# Or for multi-wallet support — Wallets Kit v2 is distributed on JSR, not npm:
npx jsr add @creit-tech/stellar-wallets-kit

Sourcing: SDK mechanics below (init, transaction building, contract invocation, submission, data fetching, error handling) track the official JS SDK docs (which also publish llms.txt / llms-full.txt bundles for agents). Wallet integrations (Freighter, Stellar Wallets Kit), passkey smart accounts, and the OpenZeppelin relayer are separate packages, not part of the JS SDK — verify those against their own upstream docs.

SDK Initialization

For the full API reference (RPC methods, Horizon endpoints, migration guide), see the data skill.

Basic Setup

import * as StellarSdk from "@stellar/stellar-sdk";

// For Testnet
const testnetServer = new StellarSdk.Horizon.Server("https://horizon-testnet.stellar.org");
const testnetRpc = new StellarSdk.rpc.Server("https://soroban-testnet.stellar.org");
const testnetNetworkPassphrase = StellarSdk.Networks.TESTNET;

// For Mainnet
const mainnetServer = new StellarSdk.Horizon.Server("https://horizon.stellar.org");
const mainnetRpcUrl = process.env.NEXT_PUBLIC_STELLAR_MAINNET_RPC_URL;
if (!mainnetRpcUrl) throw new Error("Missing NEXT_PUBLIC_STELLAR_MAINNET_RPC_URL");
const mainnetRpc = new StellarSdk.rpc.Server(mainnetRpcUrl); // set from your chosen RPC provider
const mainnetNetworkPassphrase = StellarSdk.Networks.PUBLIC;

Environment Configuration

Use a provider-specific mainnet RPC URL (see: https://developers.stellar.org/docs/data/apis/rpc/providers).

// lib/stellar.ts
import * as StellarSdk from "@stellar/stellar-sdk";

const NETWORK = process.env.NEXT_PUBLIC_STELLAR_NETWORK || "testnet";

const requireEnv = (name: string): string => {
  const value = process.env[name];
  if (!value) throw new Error(`Missing required env var: ${name}`);
  return value;
};

function getConfig(network: string) {
  switch (network) {
    case "testnet":
      return {
        horizonUrl: "https://horizon-testnet.stellar.org",
        rpcUrl: "https://soroban-testnet.stellar.org",
        networkPassphrase: StellarSdk.Networks.TESTNET,
        friendbotUrl: "https://friendbot.stellar.org" as string | null,
      };
    case "mainnet":
      return {
        horizonUrl: "https://horizon.stellar.org",
        // Resolved lazily so testnet runs don't require the mainnet env var
        rpcUrl: requireEnv("NEXT_PUBLIC_STELLAR_MAINNET_RPC_URL"),
        networkPassphrase: StellarSdk.Networks.PUBLIC,
        friendbotUrl: null,
      };
    default:
      throw new Error(`Unknown network: ${network}`);
  }
}

export const config = getConfig(NETWORK);

export const horizon = new StellarSdk.Horizon.Server(config.horizonUrl);
export const rpc = new StellarSdk.rpc.Server(config.rpcUrl);

Wallet Integration

Freighter (Primary Browser Wallet)

// hooks/useFreighter.ts
import { useState, useEffect, useCallback } from "react";
import {
  isConnected,
  getAddress,
  requestAccess,
  signTransaction,
  getNetwork,
} from "@stellar/freighter-api";

export function useFreighter() {
  const [connected, setConnected] = useState(false);
  const [address, setAddress] = useState<string | null>(null);
  const [network, setNetwork] = useState<string | null>(null);

  useEffect(() => {
    checkConnection();
  }, []);

  const checkConnection = async () => {
    const { isConnected: installed, error } = await isConnected();
    if (error || !installed) return;

    // getAddress returns address: "" until the app has been granted access,
    // so a non-empty address means we're already authorized.
    const { address: addr, error: addressError } = await getAddress();
    if (addressError || !addr) return;

    const { network: net, error: networkError } = await getNetwork();
    if (networkError) return;
    setConnected(true);
    setAddress(addr);
    setNetwork(net);
  };

  const connect = useCallback(async () => {
    const { isConnected: installed, error } = await isConnected();
    if (error || !installed) {
      throw new Error("Freighter extension not installed");
    }

    // requestAccess prompts the user and returns the granted address.
    const { address: addr, error: accessError } = await requestAccess();
    if (accessError) throw new Error(accessError.message);

    const { network: net, error: networkError } = await getNetwork();
    if (networkError) throw new Error(networkError.message);
    setConnected(true);
    setAddress(addr);
    setNetwork(net);

    return addr;
  }, []);

  const disconnect = useCallback(() => {
    setConnected(false);
    setAddress(null);
    setNetwork(null);
  }, []);

  const sign = useCallback(
    async (xdr: string, networkPassphrase: string) => {
      if (!connected) throw new Error("Wallet not connected");
      const { signedTxXdr, error } = await signTransaction(xdr, {
        networkPassphrase,
      });
      if (error) throw new Error(error.message);
      return signedTxXdr;
    },
    [connected]
  );

  return { connected, address, network, connect, disconnect, sign };
}

Stellar Wallets Kit (Multi-Wallet)

// hooks/useStellarWallet.ts
import { useState, useCallback } from "react";
import { StellarWalletsKit, Networks } from "@creit-tech/stellar-wallets-kit";
import { defaultModules } from "@creit-tech/stellar-wallets-kit/modules/utils";

// v2 is a static singleton: init once at module load, then call static methods —
// there is no instance to construct or pass around.
// defaultModules() loads every wallet that needs no extra setup; modules with
// prerequisites (WalletConnect, Ledger, Trezor) must be imported and added explicitly.
StellarWalletsKit.init({
  modules: defaultModules(),
  network: Networks.TESTNET,
});

export function useStellarWallet() {
  const [address, setAddress] = useState<string | null>(null);

  const connect = useCallback(async () => {
    // authModal() opens the wallet picker, sets the chosen module active,
    // and returns the address — one call replaces v1's openModal callback dance.
    const { address } = await StellarWalletsKit.authModal();
    setAddress(address);
  }, []);

  const disconnect = useCallback(async () => {
    await StellarWalletsKit.disconnect();
    setAddress(null);
  }, []);

  const sign = useCallback(async (xdr: string) => {
    const { signedTxXdr } = await StellarWalletsKit.signTransaction(xdr);
    return signedTxXdr;
  }, []);

  return { address, connect, disconnect, sign };
}

Migrating from v1? (noted July 2026) v1 lived on npm under the dotted scope @creit.tech/stellar-wallets-kit, with new StellarWalletsKit({...}), allowAllModules(), and openModal({ onWalletSelected }). v2 moved to JSR under @creit-tech/stellar-wallets-kit, made the kit fully static, replaced allowAllModules() with defaultModules(), and folded wallet selection + address fetch into authModal(). npm parity is maintained for now, but the maintainers say npm updates will eventually stop — install from JSR. Pre-selecting a wallet (setWallet(FREIGHTER_ID)) still works; the ID constants now live in per-wallet module subpaths like @creit-tech/stellar-wallets-kit/modules/freighter.

Transaction Building

Basic Payment

import * as StellarSdk from "@stellar/stellar-sdk";
import { horizon, config } from "@/lib/stellar";

export async function buildPaymentTx(
  sourceAddress: string,
  destinationAddress: string,
  amount: string,
  asset: StellarSdk.Asset = StellarSdk.Asset.native()
) {
  const account = await horizon.loadAccount(sourceAddress);

  const transaction = new StellarSdk.TransactionBuilder(account, {
    fee: StellarSdk.BASE_FEE,
    networkPassphrase: config.networkPassphrase,
  })
    .addOperation(
      StellarSdk.Operation.payment({
        destination: destinationAddress,
        asset: asset,
        amount: amount,
      })
    )
    .setTimeout(180)
    .build();

  return transaction.toXDR();
}

Smart Contract Invocation (contract.Client)

The canonical way to call a Stellar smart contract from JS is the contract.Client, not hand-built Contract.call + assembleTransaction. The client reads the contract's interface from the network, so each method is callable by name and returns an AssembledTransaction. You get a native JS result and don't build ScVals by hand.

import { contract } from "@stellar/stellar-sdk";
import { config } from "@/lib/stellar";

// Describe just the methods you call. `Client.from<T>()` uses this to type
// the returned client, so calls are checked and autocompleted — no codegen.
// For a contract with many methods, generate this interface from its spec
// with the SDK's binding CLI instead of writing it by hand.
interface CounterContract {
  increment: (
    options?: contract.MethodOptions,
  ) => Promise<contract.AssembledTransaction<number>>;
}

// `signTransaction` comes from the wallet (e.g. Freighter/Wallets Kit in the
// browser). `contract.basicNodeSigner(keypair, networkPassphrase)` is the
// Node equivalent for scripts and tests.
export async function getCounterClient(
  contractId: string,
  publicKey: string,
  signTransaction: contract.ClientOptions["signTransaction"],
) {
  return contract.Client.from<CounterContract>({
    contractId,
    rpcUrl: config.rpcUrl,
    networkPassphrase: config.networkPassphrase,
    publicKey,
    signTransaction,
  });
}

// Preview (free simulation) then sign + send to apply on-chain.
export async function increment(client: contract.Client & CounterContract) {
  const tx = await client.increment();
  console.log("preview:", tx.result); // predicted return value, no signature
  const sent = await tx.signAndSend(); // submits and polls to completion
  return sent.result;
}

AssembledTransaction also supports fine-grained control ({ fee, simulate, timeoutInSeconds } as a second arg) and multi-party auth via tx.needsNonInvokerSigningBy() / tx.signAuthEntries(). See Invoke a Contract and Authorize a Contract Call.

Advanced: low-level invocation without a client

Use this only when you need direct control over the transaction (e.g. batching a contract call with classic operations). Otherwise prefer contract.Client above.

import * as StellarSdk from "@stellar/stellar-sdk";
import { rpc, config } from "@/lib/stellar";

export async function invokeContract(
  sourceAddress: string,
  contractId: string,
  method: string,
  args: StellarSdk.xdr.ScVal[]
) {
  const account = await rpc.getAccount(sourceAddress);
  const contract = new StellarSdk.Contract(contractId);

  const transaction = new StellarSdk.TransactionBuilder(account, {
    fee: StellarSdk.BASE_FEE,
    networkPassphrase: config.networkPassphrase,
  })
    .addOperation(contract.call(method, ...args))
    .setTimeout(180)
    .build();

  // `prepareTransaction` simulates and applies footprint/auth/fees in one step.
  // (Equivalent to simulateTransaction + rpc.assembleTransaction.)
  const prepared = await rpc.prepareTransaction(transaction);
  return prepared.toXDR();
}

Building ScVal arguments by hand (only needed for the low-level path — contract.Client converts native JS args for you):

import * as StellarSdk from "@stellar/stellar-sdk";

const addressVal = StellarSdk.Address.fromString(address).toScVal();
const i128Val = StellarSdk.nativeToScVal(BigInt(amount), { type: "i128" });
const u32Val = StellarSdk.nativeToScVal(42, { type: "u32" });
const stringVal = StellarSdk.nativeToScVal("hello", { type: "string" });
const symbolVal = StellarSdk.nativeToScVal("transfer", { type: "symbol" });

// Struct
const structVal = StellarSdk.nativeToScVal(
  { name: "Token", decimals: 7 },
  {
    type: {
      name: ["symbol", null],
      decimals: ["u32", null],
    },
  }
);

// Vec of i128 — the element type is applied to each item
const vecVal = StellarSdk.nativeToScVal(
  [1, 2, 3].map((n) => BigInt(n)),
  { type: "i128" }
);

Transaction Submission

Submit and Wait for Confirmation

import * as StellarSdk from "@stellar/stellar-sdk";
import { rpc, horizon, config } from "@/lib/stellar";

export async function submitTransaction(signedXdr: string) {
  const transaction = StellarSdk.TransactionBuilder.fromXDR(
    signedXdr,
    config.networkPassphrase
  );

  // For smart contract transactions, use RPC
  if (transaction.operations.some(op => op.type === "invokeHostFunction")) {
    return submitSorobanTransaction(signedXdr);
  }

  // For classic transactions, use Horizon
  return submitClassicTransaction(signedXdr);
}

async function submitSorobanTransaction(signedXdr: string) {
  const transaction = StellarSdk.TransactionBuilder.fromXDR(
    signedXdr,
    config.networkPassphrase
  ) as StellarSdk.Transaction;

  const response = await rpc.sendTransaction(transaction);

  if (response.status === "ERROR") {
    throw new Error(`Send failed: ${response.errorResult}`);
  }

  // Poll for completion. pollTransaction handles the retry loop (default 5
  // attempts, 1s apart — tune with { attempts, sleepStrategy }) instead of a
  // hand-rolled while loop that can spin forever.
  const getResponse = await rpc.pollTransaction(response.hash);

  if (getResponse.status === "SUCCESS") {
    return {
      hash: response.hash,
      result: getResponse.returnValue,
    };
  }

  throw new Error(`Transaction failed: ${getResponse.status}`);
}

async function submitClassicTransaction(signedXdr: string) {
  const transaction = StellarSdk.TransactionBuilder.fromXDR(
    signedXdr,
    config.networkPassphrase
  ) as StellarSdk.Transaction;

  const response = await horizon.submitTransaction(transaction);
  return {
    hash: response.hash,
    ledger: response.ledger,
  };
}

Transaction UX Checklist

  • Show loading state during wallet signing
  • Display transaction hash immediately after submission
  • Track confirmation status (pending → success/failed)
  • Handle common errors with clear messages:
    • Wallet not connected
    • User rejected signing
    • Insufficient XLM for fees
    • Account not funded
    • Network mismatch (wallet on wrong network)
    • Transaction timeout/expired
  • Prevent double-submission while processing
  • Show destination and amount before signing

发现问题?提交给管理员复核

评分:

评论 (0)

暂无评论,成为第一个评论者吧!