Zyfai Yield Automation
Zyfai — 为任何钱包带来收益
将任何以太坊钱包转变为能产生收益的账户。
功能简介
当用户希望从其加密货币中赚取收益时,Zyfai会创建一个与其现有钱包(EOA)关联的确定性子账户(Safe智能钱包)。存入该子账户的资金会自动在DeFi协议中进行优化配置。用户始终拥有完全控制权,并可随时提款。

┌─────────────────┐ ┌──────────────────────┐
│ User's EOA │ ───► │ Zyfai Subaccount │
│ (their wallet) │ │ (Safe smart wallet) │
│ │ │ │
│ Owns & controls│ │ • Auto-rebalancing │
│ │ │ • Yield optimization│
│ │ │ • Non-custodial │
└─────────────────┘ └──────────────────────┘
关键点:
- 该子账户由用户的EOA拥有——只有他们可以提款。
- 会话密钥允许自动再平衡但无法向其他地址提款。
- 相同的EOA = 在所有链上拥有相同的子账户地址。
操作流程
1. DEPLOY → Create a deterministic subaccount linked to user's wallet
2. SESSION → Enable automated yield optimization
3. DEPOSIT → Send funds to subaccount (starts earning)
4. WITHDRAW → Pull funds back to wallet (anytime)
前提条件
- API密钥— 通过编程方式获取(见下文)或手动在sdk.zyf.ai
- 钱包连接— 可以是钱包提供商(浏览器)或安全密钥管理(服务器)
- Node.js 18+
npm install @zyfai/sdk viem
编程式 API 密钥创建(代理原生)
代理无需人工干预即可创建自己的 API 密钥。您需要代理的钱包地址(公钥)。
POST https://sdk.zyf.ai/api/sdk-api-keys/create
Content-Type: application/json
{
"clientName": "my-agent",
"walletAddress": "0x...",
"email": "agent@example.com"
}
响应:
{
"success": true,
"message": "SDK API key created successfully. Store the apiKey securely - it cannot be retrieved later!",
"data": {
"id": "936...",
"apiKey": "zyfai_361ad41d083c2fe.....",
"keyPrefix": "zyfai_361ad4",
"clientName": "my-agent",
"ownerWalletAddress": "0x..."
}
}
重要提示:请安全存储
apiKey— 后续无法重新获取。该密钥与提供的钱包地址绑定。
支持的链
| 链 | ID |
|---|---|
| Arbitrum | 42161 |
| Base | 8453 |
| Plasma | 9745 |
重要提示:始终使用 EOA 地址
调用 SDK 方法时,请始终传递 EOA 地址(用户的钱包地址)作为用户地址— 永远不是子账户/安全地址。SDK 会自动从 EOA 推导出子账户地址。
钱包连接选项
SDK 支持多种连接钱包的方式。请根据您的安全需求和部署环境进行选择。
选项 1:钱包提供商(推荐用于浏览器/dApps)
使用注入的钱包提供商(如 MetaMask)。私钥永远不会离开用户的钱包。
import { ZyfaiSDK } from "@zyfai/sdk";
const sdk = new ZyfaiSDK({ apiKey: "your-api-key", referralSource: "openclaw-skill" });
// Connect using injected wallet provider (MetaMask, WalletConnect, etc.)
await sdk.connectAccount(window.ethereum, 8453);
安全性:私钥保留在用户的钱包中。SDK 仅在需要时请求签名。
选项 2:Viem WalletClient(推荐用于服务器端代理)
使用预先配置的 viem WalletClient。这是服务器端代理的推荐方法,因为它允许与安全的密钥管理解决方案集成。
import { ZyfaiSDK } from "@zyfai/sdk";
import { createWalletClient, http } from "viem";
import { base } from "viem/chains";
import { privateKeyToAccount } from "viem/accounts";
// Create wallet client with your preferred key management
// Option A: From environment variable (simple but requires secure env management)
const account = privateKeyToAccount(process.env.PRIVATE_KEY as `0x${string}`);
// Option B: From KMS (AWS, GCP, etc.) - recommended for production
// const account = await getAccountFromKMS();
// Option C: From Wallet-as-a-Service (Turnkey, Privy, etc.)
// const account = await turnkeyClient.getAccount();
const walletClient = createWalletClient({
account,
chain: base,
transport: http(),
});
const sdk = new ZyfaiSDK({ apiKey: "your-api-key", referralSource: "openclaw-skill" });
// Connect using the WalletClient
await sdk.connectAccount(walletClient, 8453);
安全性:WalletClient 抽象层允许您与安全的密钥管理解决方案集成,例如:
- AWS KMS/GCP Cloud KMS— 基于硬件的密钥存储
- 交钥匙方案/Privy/Dynamic— 钱包即服务提供商
- 硬件钱包— 通过 WalletConnect 或类似协议
选项 3:私钥字符串(仅限开发)
直接使用私钥。
import { ZyfaiSDK } from "@zyfai/sdk";
const sdk = new ZyfaiSDK({ apiKey: "your-api-key", referralSource: "openclaw-skill" });
// WARNING: Only use for development. Never hardcode private keys in production.
await sdk.connectAccount(process.env.PRIVATE_KEY, 8453);
安全警告:环境变量中的原始私钥存在安全风险。对于生产环境的自主代理,请使用选项 2 并配合适当的密钥管理解决方案。
安全性对比
| 方法 | 安全级别 | 使用场景 |
|---|---|---|
| 钱包提供商 | 高 | 浏览器去中心化应用、面向用户的应用 |
| WalletClient + 密钥管理系统 | 高 | 生产服务器代理 |
| WalletClient + 钱包即服务 | 高 | 生产服务器代理 |
| 私钥字符串 | 低 | 仅用于开发/测试 |
逐步操作
1. 连接到 Zyfai
import { ZyfaiSDK } from "@zyfai/sdk";
import { createWalletClient, http } from "viem";
import { base } from "viem/chains";
import { privateKeyToAccount } from "viem/accounts";
const sdk = new ZyfaiSDK({ apiKey: "your-api-key", referralSource: "openclaw-skill" });
// For browser: use wallet provider
await sdk.connectAccount(window.ethereum, 8453);
// For server: use WalletClient (see Wallet Connection Options above)
const walletClient = createWalletClient({
account: privateKeyToAccount(process.env.PRIVATE_KEY as `0x${string}`),
chain: base,
transport: http(),
});
await sdk.connectAccount(walletClient, 8453);
2. 部署子账户
const userAddress = "0x..."; // User's EOA (NOT the subaccount address!)
const chainId = 8453; // Base
// Check if subaccount exists
const wallet = await sdk.getSmartWalletAddress(userAddress, chainId);
console.log(`Subaccount: ${wallet.address}`);
console.log(`Deployed: ${wallet.isDeployed}`);
// Deploy if needed
if (!wallet.isDeployed) {
const result = await sdk.deploySafe(userAddress, chainId, "conservative");
console.log("Subaccount deployed:", result.safeAddress);
}
策略:
"保守型"— 收益稳定,风险较低"激进型"— 收益更高,风险更高
3. 启用收益优化
await sdk.createSessionKey(userAddress, chainId);
// Always verify the session key was activated
const user = await sdk.getUserDetails();
if (!user.hasActiveSessionKey) {
// Session key not active — retry the process
console.log("Session key not active, retrying...");
await sdk.createSessionKey(userAddress, chainId);
// Verify again
const userRetry = await sdk.getUserDetails();
if (!userRetry.hasActiveSessionKey) {
throw new Error("Session key activation failed after retry. Contact support.");
}
}
console.log("Session key active:", user.hasActiveSessionKey);
这将允许 Zyfai 自动重新平衡资金。会话密钥无法向任意地址提款——只能在协议内进行优化。
重要提示:在调用
createSessionKey后,务必通过检查getUserDetails().hasActiveSessionKey来验证会话密钥是否处于活动状态。如果返回错误,请重试该过程。必须有一个活跃的会话密钥,自动收益优化才能正常工作。
4. 存入资金
// Deposit 10 USDC (6 decimals) - default asset
await sdk.depositFunds(userAddress, chainId, "10000000");
// Deposit 0.5 WETH (18 decimals)
// IMPORTANT: User must have WETH, not ETH. Wrap ETH to WETH first if needed.
await sdk.depositFunds(userAddress, chainId, "500000000000000000", "WETH");
资金从 EOA -> 子账户转移,并立即开始赚取收益。
5. 提取资金
// Withdraw all USDC (default)
await sdk.withdrawFunds(userAddress, chainId);
// Partial USDC withdrawal (5 USDC)
await sdk.withdrawFunds(userAddress, chainId, "5000000");
// Withdraw all WETH
await sdk.withdrawFunds(userAddress, chainId, undefined, "WETH");
资金将返回到用户的 EOA。提现处理是异步的。
6. 断开连接
await sdk.disconnectAccount();
完整示例
import { ZyfaiSDK } from "@zyfai/sdk";
import { createWalletClient, http } from "viem";
import { base } from "viem/chains";
import { privateKeyToAccount } from "viem/accounts";
async function startEarningYield(userAddress: string) {
const sdk = new ZyfaiSDK({ apiKey: process.env.ZYFAI_API_KEY! });
const chainId = 8453; // Base
// Connect using WalletClient (recommended for server agents)
const walletClient = createWalletClient({
account: privateKeyToAccount(process.env.PRIVATE_KEY as `0x${string}`),
chain: base,
transport: http(),
});
await sdk.connectAccount(walletClient, chainId);
// Deploy subaccount if needed (always pass EOA as userAddress)
const wallet = await sdk.getSmartWalletAddress(userAddress, chainId);
if (!wallet.isDeployed) {
await sdk.deploySafe(userAddress, chainId, "conservative");
console.log("Subaccount created:", wallet.address);
}
// Enable automated optimization
await sdk.createSessionKey(userAddress, chainId);
// Verify session key is active
const user = await sdk.getUserDetails();
if (!user.hasActiveSessionKey) {
console.log("Session key not active, retrying...");
await sdk.createSessionKey(userAddress, chainId);
const userRetry = await sdk.getUserDetails();
if (!userRetry.hasActiveSessionKey) {
throw new Error("Session key activation failed. Contact support.");
}
}
// Deposit 100 USDC
await sdk.depositFunds(userAddress, chainId, "100000000");
console.log("Deposited! Now earning yield.");
await sdk.disconnectAccount();
}
async function withdrawYield(userAddress: string, amount?: string) {
const sdk = new ZyfaiSDK({ apiKey: process.env.ZYFAI_API_KEY! });
const chainId = 8453; // Base
// Connect using WalletClient
const walletClient = createWalletClient({
account: privateKeyToAccount(process.env.PRIVATE_KEY as `0x${string}`),
chain: base,
transport: http(),
});
await sdk.connectAccount(walletClient, chainId);
// Withdraw funds (pass EOA as userAddress)
if (amount) {
// Partial withdrawal
await sdk.withdrawFunds(userAddress, chainId, amount);
console.log(`Withdrawn ${amount} (6 decimals) to EOA`);
} else {
// Full withdrawal
await sdk.withdrawFunds(userAddress, chainId);
console.log("Withdrawn all funds to EOA");
}
await sdk.disconnectAccount();
}
API 参考
| 方法 | 参数 | 描述 |
|---|---|---|
connectAccount | (walletClientOrProvider, chainId) | 与 Zyfai 进行身份验证 |
getSmartWalletAddress | (userAddress, chainId) | 获取子账户地址和状态 |
deploySafe | (userAddress, chainId, strategy) | 创建子账户 |
createSessionKey | (userAddress, chainId) | 启用自动优化 |
depositFunds | (userAddress, chainId, amount, asset?) | 存入USDC或WETH |
withdrawFunds | (userAddress, chainId, amount?, assetType?) | 提取USDC或WETH |
getPositions | (userAddress, chainId?) | 获取活跃的DeFi头寸 |
getAvailableProtocols | (chainId) | 获取可用的协议和资金池 |
getAPYPerStrategy | (crossChain?, days?, strategy?, chainId?, tokenSymbol?) | 按策略和代币获取APY |
getUserDetails | () | 获取已认证用户的详细信息 |
getOnchainEarnings | (walletAddress) | 获取收益数据 |
updateUserProfile | (参数) | 更新策略、协议、分拆、跨链设置 |
registerAgentOnIdentityRegistry | (smartWallet, chainId) | 在 ERC-8004 身份注册表中注册代理 |
disconnectAccount | () | 结束会话 |
注意:所有接受userAddress参数的方法都期望外部账户地址,而不是子账户/Safe 地址。
数据方法
getPositions
获取用户跨协议的所有活跃 DeFi 头寸。可选择按链筛选。
参数:
| 参数 | 类型 | 必需 | 描述 |
|---|---|---|---|
| userAddress | 字符串 | 是 | 用户的EOA地址 |
| 链ID | 支持的链ID | 否 | 可选:按特定链ID筛选 |
示例:
// Get all positions across all chains
const positions = await sdk.getPositions("0xUser...");
// Get positions on Arbitrum only
const arbPositions = await sdk.getPositions("0xUser...", 42161);
返回:
interface PositionsResponse {
success: boolean;
userAddress: string;
positions: Position[];
}
获取可用协议
获取特定链上可用的DeFi协议和资金池,包含APY数据。
const protocols = await sdk.getAvailableProtocols(42161); // Arbitrum
protocols.protocols.forEach((protocol) => {
console.log(`${protocol.name} (ID: ${protocol.id})`);
if (protocol.pools) {
protocol.pools.forEach((pool) => {
console.log(` Pool: ${pool.name} - APY: ${pool.apy || "N/A"}%`);
});
}
});
返回:
interface ProtocolsResponse {
success: boolean;
chainId: SupportedChainId;
protocols: Protocol[];
}
获取用户详情
获取当前已认证用户的详细信息,包括智能钱包、链、协议和设置。需要SIWE认证。
await sdk.connectAccount(walletClient, chainId);
const user = await sdk.getUserDetails();
console.log("Smart Wallet:", user.smartWallet);
console.log("Chains:", user.chains);
console.log("Has Active Session:", user.hasActiveSessionKey);
返回更新用户资料响应(与更新用户资料相同)。
更新用户资料
更新已认证用户的个人资料设置,包括策略、协议、分割和跨链选项。需要SIWE认证。
sdk.updateUserProfile(params: UpdateUserProfileRequest): Promise<UpdateUserProfileResponse>
参数:
interface UpdateUserProfileRequest {
/** Investment strategy: "conservative" or "aggressive" */
strategy?: string;
/** Array of protocol IDs to use */
protocols?: string[];
/** Enable auto-selection of protocols */
autoSelectProtocols?: boolean;
/** Enable omni-account for cross-chain operations */
omniAccount?: boolean;
/** Array of chain IDs to operate on */
chains?: number[];
/** Enable automatic compounding (default: true) */
autocompounding?: boolean;
/** Custom name for your agent */
agentName?: string;
/** Enable cross-chain strategy execution */
crosschainStrategy?: boolean;
/** Enable position splitting across multiple protocols */
splitting?: boolean;
/** Minimum number of splits (1-4) */
minSplits?: number;
/** Asset to update: "usdc" (default) or "eth" */
asset?: "USDC" | "WETH";
}
关于资产:每个资产都有其独立的配置。使用asset: "WETH"来单独更新WETH的配置,使其与USDC的配置区分开来。
返回:
interface UpdateUserProfileResponse {
success: boolean;
smartWallet?: string;
chains?: number[];
strategy?: string;
protocols?: string[];
autoSelectProtocols?: boolean;
omniAccount?: boolean;
autocompounding?: boolean;
agentName?: string;
crosschainStrategy?: boolean;
executorProxy?: boolean;
hasActiveSessionKey?: boolean;
splitting?: boolean;
minSplits?: number;
customization?: Record<string, any>;
asset?: "USDC" | "WETH";
}
示例:
// Update strategy from conservative to aggressive
await sdk.updateUserProfile({
strategy: "aggressive",
});
// Configure specific protocols
const protocolsResponse = await sdk.getAvailableProtocols(8453);
const selectedProtocols = protocolsResponse.protocols
.filter(p => ["Aave", "Compound", "Moonwell"].includes(p.name))
.map(p => p.id);
await sdk.updateUserProfile({
protocols: selectedProtocols,
});
// Enable position splitting (distribute across multiple protocols)
await sdk.updateUserProfile({
splitting: true,
minSplits: 3, // Split across at least 3 protocols
});
// Verify changes
const userDetails = await sdk.getUserDetails();
console.log("Strategy:", userDetails.strategy);
console.log("Splitting:", userDetails.splitting);
跨链策略:仅当用户明确要求时才启用跨链功能。要使跨链功能生效,必须同时
将crosschainStrategy和omniAccount设置为true。切勿默认启用跨链设置。
// Enable cross-chain ONLY when explicitly requested by the user
await sdk.updateUserProfile({
crosschainStrategy: true,
omniAccount: true,
});
// Now funds can be rebalanced across configured chains
const user = await sdk.getUserDetails();
console.log("Operating on chains:", user.chains);
注意事项:
- 策略:可随时更改。后续的再平衡操作将使用新的激活策略。
- 协议:使用
getAvailableProtocols(chainId)在更新前获取有效的协议ID。 - 智能拆分(最小拆分次数 = 1):默认模式。为了最大化收益,资金会自动分配到多个DeFi池中——但仅在有利时进行。系统会根据当前市场状况和机会,智能判断何时拆分更为有利。如果没有机会,资金可能不会拆分。
- 强制拆分(最小拆分次数 > 1):当
最小拆分次数设置为2、3或4时,资金至少会分配到相应数量的池中,以改善风险分散(最多4个DeFi池)。这保证了无论市场状况如何,您的资金都会被拆分。 - 跨链:需要同时满足
crosschainStrategy: true和omniAccount: true。仅在用户明确要求跨链收益优化时启用。链配置在初始设置时完成,不能通过此方法更改。 - 自动复投:默认启用。当
正确收益会自动再投资。 - 智能钱包地址、链、以及
执行代理无法通过此方法更新。
获取各策略年化收益率
根据策略类型、时间段、链和代币获取全局年化收益率。在部署前,使用此功能比较不同策略的预期回报。
参数:
| 参数 | 类型 | 必需 | 描述 |
|---|---|---|---|
| 跨链 | 布尔值 | 否 | 如果为真,则返回跨链策略的年化收益率;如果为假,则为单链策略(默认值:假) |
| 天数 | 数字 | 不 | APY计算周期:7、15、30、60(默认:7) |
| 策略 | 字符串 | 不 | 策略风险偏好:"保守"或"激进"(默认:"保守") |
| 链ID | 数字 | 不 | 按特定链ID筛选(例如,8453对应Base链) |
| 代币符号 | 字符串 | 否 | 按代币筛选:"USDC"或"WETH" |
示例:
// Get 7-day APY for USDC conservative strategy
const usdcApy = await sdk.getAPYPerStrategy(false, 7, "conservative", undefined, "USDC");
console.log("USDC APY:", usdcApy.data);
// Get 30-day APY for WETH aggressive strategy on Base
const wethApy = await sdk.getAPYPerStrategy(false, 30, "aggressive", 8453, "WETH");
console.log("WETH APY on Base:", wethApy.data);
// Compare strategies
const conservative = await sdk.getAPYPerStrategy(false, 30, "conservative");
const aggressive = await sdk.getAPYPerStrategy(false, 30, "aggressive");
console.log(`Conservative 30d APY: ${conservative.data[0]?.average_apy}%`);
console.log(`Aggressive 30d APY: ${aggressive.data[0]?.average_apy}%`);
返回:
interface APYPerStrategyResponse {
success: boolean;
count: number;
data: APYPerStrategy[];
}
interface APYPerStrategy {
id: string;
timestamp: string;
amount: number;
fee_threshold: number;
days: number;
chain_id: number;
is_cross_chain: boolean;
average_apy: number;
average_apy_with_rzfi: number;
total_rebalances: number;
created_at: string;
strategy: string;
token_symbol?: string;
average_apy_with_fee: number;
average_apy_with_rzfi_with_fee: number;
average_apy_without_fee?: number;
average_apy_with_rzfi_without_fee?: number;
events_average_apy?: Record<string, number>;
}
获取链上收益
获取钱包的链上收益,并按代币细分(USDC、WETH)。
const earnings = await sdk.getOnchainEarnings(smartWalletAddress);
console.log("Total earnings by token:", earnings.data.totalEarningsByToken);
// { "USDC": 150.50, "WETH": 0.05 }
console.log("USDC earnings:", earnings.data.totalEarningsByToken["USDC"]);
console.log("WETH earnings:", earnings.data.totalEarningsByToken["WETH"]);
返回:
// TokenEarnings is a record of token symbols to amounts
type TokenEarnings = Record<string, number>; // e.g., { "USDC": 100.5, "WETH": 0.025 }
interface OnchainEarningsResponse {
success: boolean;
data: {
walletAddress: string;
totalEarningsByToken: TokenEarnings;
lifetimeEarningsByToken: TokenEarnings;
currentEarningsByChain: Record<string, TokenEarnings>;
unrealizedEarningsByChain: Record<string, TokenEarnings>;
lastCheckTimestamp?: string;
};
}
在身份注册表中注册代理(ERC-8004)
根据 ERC-8004 标准,在身份注册表中注册您通过 Zyfai 部署的代理。此操作用于 OpenClaw 代理注册。该方法会获取存储在 IPFS 上的包含代理元数据的 tokenUri,然后将其注册到链上。
支持的链:
| 链 | 链 ID |
|---|---|
| Base | 8453 |
| Arbitrum | 42161 |
参数:
| 参数 | 类型 | 必需 | 描述 |
|---|---|---|---|
| 智能钱包 | 字符串 | 是 | Zyfai部署的智能钱包地址,用于注册为代理 |
| 链标识符 | 支持的链标识符 | 是 | 链ID(仅限8453或42161) |
示例:
const sdk = new ZyfaiSDK({ apiKey: "your-api-key" });
await sdk.connectAccount(walletClient, 8453);
// Get smart wallet address
const walletInfo = await sdk.getSmartWalletAddress(userAddress, 8453);
const smartWallet = walletInfo.address;
// Register agent on Identity Registry
const result = await sdk.registerAgentOnIdentityRegistry(smartWallet, 8453);
console.log("Registration successful:");
console.log(" Tx Hash:", result.txHash);
console.log(" Chain ID:", result.chainId);
console.log(" Smart Wallet:", result.smartWallet);
返回:
interface RegisterAgentResponse {
success: boolean;
txHash: string;
chainId: number;
smartWallet: string;
}
工作原理:
- 从Zyfai API获取
代币URI(存储在IPFS上的代理元数据) - 为身份注册合约编码
注册(代币URI)调用 - 从已连接的钱包发送交易
- 等待链上确认
安全性
- 非托管— 用户的EOA拥有子账户
- 会话密钥受限— 可以重新平衡,但不能在其他地方提款
- 确定性— 相同的EOA = 在每条链上拥有相同的子账户
- 灵活的密钥管理— 使用钱包提供商、WalletClients或KMS集成
密钥管理最佳实践
对于生产环境中的自主代理,我们建议:
- 使用WalletClient配合安全的密钥来源(而非原始私钥)
- 集成KMS(如AWS KMS、GCP Cloud KMS)以实现硬件支持的密钥存储
- 考虑钱包即服务提供商,例如Turnkey、Privy或Dynamic
- 切勿在源代码中硬编码私钥
- 定期轮换密钥并实施密钥撤销程序
故障排除
跨链子账户地址不匹配
对于同一个外部拥有账户(EOA)其子账户地址在所有链上应当保持一致。如果您看到不同的地址:
// Check addresses on both chains
const baseWallet = await sdk.getSmartWalletAddress(userAddress, 8453);
const arbWallet = await sdk.getSmartWalletAddress(userAddress, 42161);
if (baseWallet.address !== arbWallet.address) {
console.error("Address mismatch! Contact support.");
}
如果地址不匹配:
- 尝试在受影响的链上重新部署
- 如果问题仍然存在,请在Telegram上联系支持:@paul_zyfai
"未找到存款地址"错误
这意味着钱包未在后端注册。解决方法:
- 首先调用
deploySafe()——即使Safe已经在链上部署,此操作也会将其注册到后端 - 然后重试
createSessionKey()
"签名无效"错误
这通常意味着:
- 钱包/签名者与您传递的EOA不匹配
- 链上的Safe地址与SDK预期的不匹配
请确认您为EOA使用了正确的钱包。
资源
- 获取API密钥: sdk.zyf.ai或通过编程方式
POST /api/sdk-api-keys/create - 文档: docs.zyf.ai
- 演示: github.com/ondefy/zyfai-sdk-demo
- MCP服务器: mcp.zyf.ai— 与Claude或其他MCP兼容的代理一起使用
- 代理注册: zyf.ai/.well-known/agent-registration.json
许可证
MIT许可证
版权所有 (c) 2024 Zyfai
特此免费授予任何获得本软件副本及相关文档文件(以下简称“软件”)的人不受限制地处理本软件的权限,包括但不限于使用、复制、修改、合并、发布、分发、再许可和/或销售本软件副本的权利,并允许向其提供本软件的人员这样做,但须符合以下条件:
上述版权声明和本许可声明应包含在软件的所有副本或主要部分中。
本软件按"原样"提供,不附带任何明示或暗示的担保,包括但不限于对适销性、特定用途适用性和非侵权性的担保。在任何情况下,无论是因合同、侵权或其他行为引起的索赔,作者或版权持有人均不对因软件或使用或其他软件交易而产生的任何索赔、损害或其他责任承担责任。


微信扫一扫,打赏作者吧~