> For the complete documentation index, see [llms.txt](https://pacifica.gitbook.io/docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://pacifica.gitbook.io/docs/api-documentation/api/signing/implementation.md).

# Implementation

### 1. Setup and Initialization:

```python
import time
import base58
import requests
from solders.keypair import Keypair

PRIVATE_KEY = "your_private_key_here"

# Generate keypair from private key
keypair = Keypair.from_bytes(base58.b58decode(PRIVATE_KEY))
public_key = str(keypair.pubkey())
```

### 2. Choose Endpoint and Define Operation Type

For this example, we use the order creation endpoint. Refer to [Operation Types](https://docs.pacifica.fi/api-documentation/api/signing/operation-types) for a list of all types and corresponding API endpoints.

```python
API_URL = "https://api.pacifica.fi/api/v1/orders/create"
operation_type = "create_order"
operation_data = {
    "symbol": "BTC",
    "price": "100000",
    "amount": "0.1",
    "side": "bid",
    "tif": "GTC",
    "reduce_only": False,
    "client_order_id": str(uuid.uuid4()),
}
```

### 3. Create Signature Header

Note that all times specified are denoted in milliseconds.\
\
The `"expiry_window"` field is optional, and defaults to 30\_000 (30 seconds) if not specified in the header.

```python
# Get current timestamp in milliseconds
timestamp = int(time.time() * 1_000)

signature_header = {
    "timestamp": timestamp,
    "expiry_window": 5_000,  
    "type": "create_order",
}
```

### 4. Combine Header and Payload

```python
data_to_sign = {
    **signature_header,
    "data": operation_data,
}

```

In the case of our example, this creates:

```python
 {
     "timestamp": 1748970123456,
     "expiry_window": 5000,
     "type": "create_order",
     "data": {
         "symbol": "BTC",
         "price": "100000",
         "amount": "0.1",
         "side": "bid",
         "tif": "GTC",
         "reduce_only": False,
         "client_order_id": "12345678-1234-1234-1234-123456789abc"
     }
 }
```

Note that data must be in same level as other headers.

### 5. Recursively Sort JSON Keys

```python
def sort_json_keys(value):
    if isinstance(value, dict):
        sorted_dict = {}
        for key in sorted(value.keys()):
            sorted_dict[key] = sort_json_keys(value[key])
        return sorted_dict
    elif isinstance(value, list):
        return [sort_json_keys(item) for item in value]
    else:
        return value

sorted_message = sort_json_keys(data_to_sign)
```

In the case of our example, this creates:

```python
{
     "data": {
         "amount": "0.1",
         "client_order_id": "12345678-1234-1234-1234-123456789abc",
         "price": "100000",
         "reduce_only": false,
         "side": "bid",
         "symbol": "BTC",
         "tif": "GTC"
     },
     "expiry_window": 5000,
     "timestamp": 1748970123456,
     "type": "create_order"
 }
```

Note that the recursive sorting alphabetically sorts \*all\* levels

### 6. Create Compact JSON

Compact JSON string with no whitespace and standardized seperators

```python
import json

compact_json = json.dumps(sorted_message, separators=(",", ":"))
```

In the case of our example, this creates:

```
{"data":{"amount":"0.1","client_order_id":"12345678-1234-1234-1234-123456789abc","price":"100000","reduce_only":false,"side":"bid","symbol":"BTC","tif":"GTC"},"expiry_window":5000,"timestamp":1748970123456,"type":"create_order"}
```

This ensures that all logically identical messages will always produce \*identical\* signatures

### 7. Convert to Bytes and Generate Signature

Messages are converted to UTF-8 bytes for signing. The signature generated is then converted to Base58 string for transmission.

<pre class="language-python"><code class="lang-python"><strong># Convert to UTF-8 bytes
</strong><strong>message_bytes = compact_json.encode("utf-8")
</strong>
# Sign message bytes using your private key
signature = keypair.sign_message(message_bytes)

# Convert signature to Base58 string
signature_b58 = base58.b58encode(bytes(signature)).decode("ascii")

# Expect an output similar to:
# "5j1Vy9UqYUF2jKD9r2Lv5AoMWHJuW5a1mqVzEhC9SJL5GqbPkGEQKpW3UZmKXr4UWrHMJ5xHQFMJkZWE8J5VyA"
</code></pre>

### 8. Build Final Request

Build the header with generated authentication info and combine with operation data (NOT the "data" wrapper!)

```python
request_header = {
    "account": public_key,
    "agent_wallet": None,
    "signature": signature_b58,
    "timestamp": signature_header["timestamp"],
    "expiry_window": signature_header["expiry_window"],
}

final_request = {
    **request_header,
    **operation_data,  # Use the ORIGINAL create order fields
}
```

In the case of our example, the final request looks like:

```python
 {
     "account": "6ETnufiec2CxVWTS4u5Wiq33Zh5Y3Qm6Pkdpi375fuxP",
     "agent_wallet": null,
     "signature": "5j1Vy9UqYUF2jKD9r2Lv5AoMWHJuW5a1mqVzEhC9SJL5GqbPkGEQKpW3UZmKXr4UWrHMJ",
     "timestamp": 1748970123456,
     "expiry_window": 5000,
     "symbol": "BTC",
     "price": "100000",
     "amount": "0.1",
     "side": "bid",
     "tif": "GTC",
     "reduce_only": false,
     "client_order_id": "12345678-1234-1234-1234-123456789abc"
 }
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://pacifica.gitbook.io/docs/api-documentation/api/signing/implementation.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
