> ## Documentation Index
> Fetch the complete documentation index at: https://veniceai-docs-web3-key-siwe-challenge.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# إنشاء مفتاح API للوكلاء المستقلين

> أصدر مفتاح Venice API ذاتيًا من وكيل ذكاء اصطناعي على السلسلة بتكديس VVV على Base وتوقيع رسالة تحدٍّ SIWE صادرة من Venice بمحفظة.

يمكن لوكيل ذكاء اصطناعي يتحكم بمحفظة على Base أن يصدر مفتاح Venice API الخاص به دون أي تدخل بشري. يحصل الوكيل على VVV، ويكدّسها (stakes)، ويطلب رسالة تحدٍّ قصيرة الأمد مرتبطة بعنوان محفظته، ثم يوقّعها ويُرسلها للحصول على مفتاح API جديد مرتبط بمحفظة الـ staking.

يستعرض هذا الدليل التدفق الكامل من البداية إلى النهاية ويغطي خيارات التمويل لدفع الاستدلال فعليًا بعد إصدار المفتاح.

## المتطلبات

* محفظة EVM على Base يتحكم بها الوكيل (مفتاح خاص في متغير بيئة أو مدير أسرار).
* كمية صغيرة من ETH على Base للـ gas (الـ staking يتطلب معاملتين: `approve` ثم `stake`).
* أي كمية غير صفرية من VVV للـ stake. تتطلب endpoint الإصدار فقط أن يكون لدى المحفظة رصيد sVVV غير صفري، لذا VVV واحد يكفي لإصدار مفتاح. راجع [الدفع للاستدلال](#paying-for-inference) لمعرفة ما تحتاجه لاستدعاء endpoints مدفوعة فعليًا.

<Tip>
  استخدم محفظة وكيل مخصصة بدلًا من محفظة الخزينة. يوقّع المفتاح الخاص للمحفظة كل رسالة تحدٍّ من Venice، لذا يجب أن يكون نطاق تأثيرها صغيرًا.
</Tip>

## الخطوات

<Steps>
  <Step title="احصل على VVV">
    أرسل VVV إلى محفظة الوكيل، أو اجعل الوكيل يقوم بمبادلة على DEX مثل [Aerodrome](https://aerodrome.finance/swap?from=eth\&to=0xacfe6019ed1a7dc6f7b508c02d1b04ec88cc21bf\&chain0=8453\&chain1=8453) أو [Uniswap](https://app.uniswap.org/swap?chain=base\&inputCurrency=NATIVE\&outputCurrency=0xacfe6019ed1a7dc6f7b508c02d1b04ec88cc21bf).

    عقد token VVV على Base: `0xacfE6019Ed1A7Dc6f7B508C02d1b04ec88cC21bf`
  </Step>

  <Step title="قم بـ stake لـ VVV مع Venice">
    قم بـ stake لـ VVV في [Venice Staking Smart Contract](https://basescan.org/address/0x321b7ff75154472b18edb199033ff4d116f340ff#code) عند `0x321b7ff75154472B18EDb199033fF4D116F340Ff`. هذه معاملتان:

    1. `approve(spender, amount)` على token VVV، حيث `spender` هو عقد الـ staking.
    2. `stake(amount)` على عقد الـ staking.

    <Frame as="div">
      <img src="https://mintcdn.com/veniceai-docs-web3-key-siwe-challenge/gsQAAKgvxVIs7Yrg/images/guides/SC-Stake.png?fit=max&auto=format&n=gsQAAKgvxVIs7Yrg&q=85&s=a6146194096d33bc992caf2257cfdc25" alt="Smart Contract Staking" width="812" height="324" data-path="images/guides/SC-Stake.png" />
    </Frame>

    عندما تؤكَّد المعاملة الثانية، ينخفض رصيد VVV للمحفظة ويزداد رصيد sVVV الخاص بها بنفس المقدار. تقرأ endpoint الإصدار رصيد sVVV لتأكيد أن المحفظة قد قامت بـ stake.
  </Step>

  <Step title="اطلب رسالة تحدٍّ للمحفظة">
    استدعِ `GET /api/v1/api_keys/generate_web3_key?address=<wallet address>` للحصول على رسالة تحدٍّ [EIP-4361](https://eips.ethereum.org/EIPS/eip-4361) (Sign-In with Ethereum) قصيرة الأمد. الـ endpoint غير مُصادَقة، لكن رسالة التحدي مرتبطة بالعنوان الذي ترسله ولا يمكن استخدامها إلا بتلك المحفظة.

    ```bash theme={null}
    curl --request GET \
      --url 'https://api.venice.ai/api/v1/api_keys/generate_web3_key?address=<wallet address>'
    ```

    تحتوي الاستجابة على `message` و `nonce` و `expiresAt`:

    ```json theme={null}
    {
      "data": {
        "message": "api.venice.ai wants you to sign in with your Ethereum account:\n0x...\n\nAuthorize Venice API key creation. Only sign this on venice.ai — anyone holding this signature can create an API key on your Venice account.\n\nURI: https://api.venice.ai/api/v1/api_keys/generate_web3_key\nVersion: 1\nChain ID: 8453\nNonce: 9f2c1d6b4a8e05337c1b9d2e6f4a7c81\nIssued At: 2026-06-30T11:02:41.167Z\nExpiration Time: 2026-06-30T11:17:41.167Z\nResources:\n- urn:venice:api-key:create",
        "nonce": "9f2c1d6b4a8e05337c1b9d2e6f4a7c81",
        "expiresAt": "2026-06-30T11:17:41.167Z"
      },
      "success": true
    }
    ```

    تنتهي صلاحية رسالة التحدي بعد 15 دقيقة من إصدارها وهي **للاستخدام مرة واحدة** — تُستهلك عند إصدار أول مفتاح بها. اطلب رسالة جديدة لكل مفتاح.
  </Step>

  <Step title="وقّع رسالة التحدي بمحفظة الـ staking">
    وقّع سلسلة `message` كما هي بالمحفظة التي تحمل VVV المُكدَّس. هذا `personal_sign` قياسي. كلا `ethers.Wallet.signMessage(message)` و `account.signMessage({ message })` من `viem` يُنتجان التوقيع الصحيح.

    لا تُعِد تنسيق الرسالة أو تغيير أسطرها أو توليدها من جديد. تتحقق Venice من التوقيع على البايتات نفسها التي أصدرتها، وتعيد فحص `domain` و `URI` و `Chain ID` ونص البيان والعنوان داخلها بشكل مستقل.
  </Step>

  <Step title="أصدر مفتاح API">
    `POST` العنوان والتوقيع ورسالة التحدي إلى نفس الـ endpoint، بالإضافة إلى نوع المفتاح الذي تريده.

    ```bash theme={null}
    curl --request POST \
      --url https://api.venice.ai/api/v1/api_keys/generate_web3_key \
      --header 'Content-Type: application/json' \
      --data '{
        "address": "<wallet address>",
        "signature": "<signature of the challenge message>",
        "message": "<the unmodified challenge message>",
        "apiKeyType": "INFERENCE",
        "description": "Agent key minted on <date>"
      }'
    ```

    الحقول المطلوبة: `address` و `signature` و `message` و `apiKeyType` (`INFERENCE` أو `ADMIN`).

    الحقول الاختيارية: `description` و `expiresAt` و `consumptionLimit` (يحد من إجمالي الإنفاق على هذا المفتاح، بالعملة `usd` أو `vcu` أو `diem`).

    عند النجاح، تحتوي الاستجابة على سلسلة `apiKey` المُصدَرة. خزّنها في مخزن أسرار الوكيل واستخدمها كـ Bearer token عادي (`Authorization: Bearer <key>`).
  </Step>
</Steps>

## مثال شامل

يستخدم المثال أدناه محفظة حقيقية من متغير بيئة بدلًا من محفظة مُولَّدة عشوائيًا. المحفظة العشوائية ليس لديها VVV مُكدَّس وسيتم رفض الإصدار بخطأ `Wallet has no staked VVV on Base`.

```typescript theme={null}
import { ethers } from "ethers"

const wallet = new ethers.Wallet(process.env.WALLET_PRIVATE_KEY!)
const address = wallet.address

const challengeResponse = await fetch(
  `https://api.venice.ai/api/v1/api_keys/generate_web3_key?address=${address}`,
)
const { data: { message } } = await challengeResponse.json()

const signature = await wallet.signMessage(message)

const mintResponse = await fetch("https://api.venice.ai/api/v1/api_keys/generate_web3_key", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    address,
    signature,
    message,
    apiKeyType: "INFERENCE",
    description: "Agent key",
  }),
})

const result = await mintResponse.json()
if (!mintResponse.ok) {
  throw new Error(`Mint failed: ${result.error}`)
}

console.log("Minted key:", result.data.apiKey)
```

## مرجع الأخطاء

تُعيد الـ endpoint رسائل خطأ محددة وقابلة للتنفيذ. عيّن هذه في الوكيل حتى يتمكن من تقرير ما إذا كان سيعيد المحاولة أم يطلب رسالة تحدٍّ جديدة أم يتوقف.

| الحالة | تحتوي رسالة الخطأ                                    | ما يعنيه                                                              | ما يجب فعله                                                      |
| ------ | ---------------------------------------------------- | --------------------------------------------------------------------- | ---------------------------------------------------------------- |
| `400`  | `Invalid wallet address`                             | حقل `address` ليس عنوان EVM صالحًا.                                   | صحّح العنوان وأعد الإرسال.                                       |
| `400`  | `The challenge has expired`                          | انتهت صلاحية رسالة التحدي قبل أن توقّعها وترسلها.                     | اطلب رسالة تحدٍّ جديدة، ووقّعها، وأرسلها فورًا.                  |
| `400`  | `This challenge has already been used`               | استُخدمت رسالة التحدي بالفعل. كل رسالة تُصدر مفتاحًا واحدًا كحد أقصى. | اطلب رسالة تحدٍّ جديدة لكل مفتاح تصدره.                          |
| `400`  | `issued for a different wallet address`              | الـ `address` المُرسَل ليس العنوان الذي صدرت له رسالة التحدي.         | اطلب رسالة تحدٍّ مع `?address=` مضبوطًا على المحفظة التي ستوقّع. |
| `400`  | `not a valid Venice API key authorization challenge` | الـ `message` ليس رسالة تحدٍّ من Venice، أو تم تعديله.                | أرسل سلسلة الـ `message` بالضبط المُعادة من endpoint `GET`.      |
| `400`  | `The challenge statement was modified`               | تم تغيير سطر البيان بعد الإصدار.                                      | وقّع الرسالة كما هي.                                             |
| `400`  | `The challenge domain must be "api.venice.ai"`       | تم تغيير سطر `domain`.                                                | وقّع الرسالة كما هي.                                             |
| `400`  | `Wallet signature does not match`                    | الـ `signature` لا يطابق `address` للـ `message` المُعطى.             | وقّع الرسالة بالضبط بالمحفظة التي تملك `address`.                |
| `400`  | `Could not verify wallet signature`                  | فشل استدعاء RPC للتحقق من التوقيع (مؤقت).                             | أعد المحاولة مع backoff.                                         |
| `400`  | `Wallet has no staked VVV on Base`                   | المحفظة لديها رصيد sVVV صفر.                                          | قم بـ stake لـ VVV أولًا، ثم أعد المحاولة.                       |

## لماذا ترتبط رسالة التحدي بالمحفظة وتُستخدم مرة واحدة

رسالة التحدي هي رسالة EIP-4361 مقروءة للبشر وليست token غامضًا، وتوفّر ثلاث حمايات مهمة إذا طُلب يومًا من محفظة توقيع واحدة خارج وكيلك الخاص:

* **الارتباط بالعنوان.** تذكر رسالة التحدي المحفظة التي صدرت لها. لا يمكن لمحفظة أخرى توقيع رسالة تحدٍّ حصل عليها طرف مختلف واستخدامها.
* **nonce للاستخدام مرة واحدة.** تتتبع Venice الـ nonce على الخادم وتستهلكه عند أول إصدار ناجح. التوقيع الواحد يُصدر مفتاحًا واحدًا بالضبط، لذا لا يمكن إعادة استخدام توقيع مُلتقَط للحصول على مفاتيح إضافية.
* **بيان مقروء.** تنص الرسالة صراحةً على أن التوقيع يُصرّح بإنشاء مفتاح Venice API، فتُظهر واجهة المحفظة مثل MetaMask للموقّع ما يوافق عليه بدلًا من كتلة بيانات ثنائية.

<Warning>
  تعامل مع التوقيع على هذه الرسالة كما لو كنت تمنح صلاحية إنشاء مفاتيح API على حسابك في Venice. لا توقّع إلا رسائل التحدي التي يكون فيها سطر `domain` هو `api.venice.ai` وينص بيانها على إنشاء مفتاح Venice API. يمكن لمفتاح `ADMIN` إنشاء مفاتيح أخرى وحذفها والإنفاق من أرصدة DIEM والأرصدة المُجمّعة و USD الخاصة بك.
</Warning>

## الدفع للاستدلال

إصدار مفتاح والقدرة على استدعاء endpoints مدفوعة به شيئان منفصلان. المفتاح المُصدَر حديثًا يصادق بشكل صحيح لكنه لا يستطيع استدعاء endpoints مدفوعة (مثل `/chat/completions`) حتى يكون لدى حساب المحفظة رصيد قابل للإنفاق.

يمكن للمفتاح المُصدَر الإنفاق من حساب المستخدم بترتيب الأولوية هذا: DIEM، ثم الاعتمادات المُجمَّعة، ثم الدولار الأمريكي.

| مصدر التمويل               | مستقل؟     | كيف                                                                                                                                                                                                                             |
| -------------------------- | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **DIEM من VVV staking**    | نعم        | حصة DIEM اليومية للمحفظة تتناسب مع حصتها في تجمع الـ staking. يحتاج الحساب إلى 0.1 على الأقل من DIEM المُكدَّسة ليكون أي DIEM قابلًا للإنفاق. الـ stakes الأكبر تكسب DIEM يومية أكثر بشكل متناسب، تُحدَّث كل epoch (00:00 UTC). |
| **USD عبر Stripe**         | لا (متصفح) | سجّل الدخول إلى venice.ai بنفس المحفظة (Sign-In-With-Ethereum). تجد اللوحة سجل المستخدم الموجود. أضف اعتمادات في Settings، API.                                                                                                 |
| **اشتراك Coinbase crypto** | لا (متصفح) | تسجيل دخول بنفس المحفظة، ثم اشترك عبر اللوحة. يعيد التدفق التوجيه إلى Coinbase Commerce للدفع الفعلي، لذا لا يمكن تشغيله من سكريبت.                                                                                             |
| **Coinbase onramp**        | لا (متصفح) | تسجيل دخول بنفس المحفظة، ثم استخدم widget onramp في اللوحة. مُستضاف على واجهة Coinbase.                                                                                                                                         |

إذا احتاج الوكيل إلى مسار تمويل crypto-native بالكامل وبدون رأس، فإن الخيارات الأنظف هي:

1. **قم بـ stake لمزيد من VVV** بحيث تغطي حصة DIEM اليومية إنفاق الوكيل. يلتقط المفتاح المُصدَر هذا تلقائيًا.
2. **استخدم [تدفق محفظة x402](/guides/integrations/x402-venice-api) بدلًا من مفتاح API.** مع x402 يوقّع الوكيل رسالة Sign-In-With-X لكل طلب، ويشحن مباشرة بـ USDC على Base أو Solana عبر `POST /api/v1/x402/top-up`، ويدفع لكل طلب. رصيد x402 USDC مرتبط بالمحفظة وليس بالمستخدم، لذا فهو لا يظهر كرصيد لمفتاح Bearer المُصدَر، لكنه يسمح لنفس المحفظة بدفع الاستدلال برمجيًا.

## موارد ذات صلة

<CardGroup cols={2}>
  <Card title="Crypto والوكلاء" icon="link" href="/guides/integrations/crypto-rpc-agents">
    استخدم Venice كموفّر للنموذج وكطبقة RPC للبلوكشين معًا للوكلاء المستقلين.
  </Card>

  <Card title="مصادقة محفظة x402" icon="wallet" href="/guides/integrations/x402-venice-api">
    ادفع لكل طلب بـ USDC على Base أو Solana، دون الحاجة إلى مفتاح API.
  </Card>

  <Card title="Endpoint إنشاء مفتاح Web3 API" icon="code" href="/api-reference/endpoint/api_keys/generate_web3_key/post">
    مرجع endpoint لـ endpoint الإصدار.
  </Card>

  <Card title="دليل مفتاح API القياسي" icon="key" href="/guides/getting-started/generating-api-key">
    للمستخدمين الذين يفضلون إصدار مفتاح من اللوحة.
  </Card>
</CardGroup>
