# Go语言调用 Mefree.NET API

本指南介绍如何使用 **Go语言** 调用 Mefree.NET API，包括签名生成、HTTP 请求构建以及接口调用示例。

***

#### **1. 签名规则概述**

**1.1 签名字符串规则**

Mefree.NET API 使用签名机制验证身份，请确保按照以下规则生成签名：

1. 拼接待签名字符串：

   ```
   sign = timestamp + method + requestPath
   ```

   * **timestamp**：UTC 时间，格式为 ISO 8601，例如：`2024-11-26T12:34:56.789Z`。
   * **method**：HTTP 方法，例如 `GET` 或 `POST`。
   * **requestPath**：API 请求路径（包括查询参数），例如：
     * `/api/config`
     * `/api/order?quantity=65000&target_address=TRON_ADDRESS&period=1`
2. 使用 **HMAC-SHA256** 算法，结合 API 的 **Secret Key** 对拼接字符串进行加密。
3. 将加密结果用 **Base64** 编码，得到最终的签名值。

***

**1.2 请求头参数**

每个请求必须包含以下 HTTP 头：

* `Content-Type: application/json`
* `MF-ACCESS-KEY`: 您的 API Key。
* `MF-ACCESS-SIGN`: 生成的签名值。
* `MF-ACCESS-TIMESTAMP`: 当前 UTC 时间戳。

***

#### **2. 环境准备**

确保您的开发环境已安装 **Go**。以下是需要导入的标准库和第三方库：

* **`crypto/hmac`**：用于生成 HMAC 签名。
* **`crypto/sha256`**：用于计算 SHA256 哈希。
* **`encoding/base64`**：用于 Base64 编码。
* **`time`**：用于获取 UTC 时间戳。
* **`net/http` 和 `io/ioutil`**：用于发送 HTTP 请求。

***

#### **3. 签名生成方法**

以下是基于 Go 语言的签名生成方法：

```go
package main

import (
	"crypto/hmac"
	"crypto/sha256"
	"encoding/base64"
	"fmt"
	"time"
)

// 生成签名
func generateSignature(timestamp, method, requestPath, secretKey string) string {
	message := timestamp + method + requestPath
	h := hmac.New(sha256.New, []byte(secretKey))
	h.Write([]byte(message))
	signature := base64.StdEncoding.EncodeToString(h.Sum(nil))
	return signature
}

// 获取当前 UTC 时间戳（ISO 8601 格式）
func getUtcTimestamp() string {
	return time.Now().UTC().Format("2006-01-02T15:04:05.000Z")
}
```

***

#### **4. 通用请求方法**

以下代码展示了一个通用的 HTTP 请求函数，包含签名生成和请求头构建：

```go
package main

import (
	"bytes"
	"fmt"
	"io/ioutil"
	"net/http"
)

// 配置基础信息
const (
	BASE_URL   = "https://api.mefree.net"
	API_KEY    = "your_api_key"    // 替换为您的 API Key
	SECRET_KEY = "your_secret_key" // 替换为您的 Secret Key
)

// 发送 API 请求
func sendRequest(method, requestPath string) ([]byte, error) {
	// 获取当前 UTC 时间戳
	timestamp := getUtcTimestamp()

	// 生成签名
	signature := generateSignature(timestamp, method, requestPath, SECRET_KEY)

	// 构造请求
	client := &http.Client{}
	url := BASE_URL + requestPath
	req, err := http.NewRequest(method, url, nil)
	if err != nil {
		return nil, err
	}

	// 添加请求头
	req.Header.Add("Content-Type", "application/json")
	req.Header.Add("MF-ACCESS-KEY", API_KEY)
	req.Header.Add("MF-ACCESS-SIGN", signature)
	req.Header.Add("MF-ACCESS-TIMESTAMP", timestamp)

	// 发送请求
	resp, err := client.Do(req)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

	// 读取响应
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return nil, err
	}

	if resp.StatusCode != http.StatusOK {
		return nil, fmt.Errorf("HTTP %d: %s", resp.StatusCode, string(body))
	}

	return body, nil
}
```

***

#### **5. 示例接口调用**

**5.1 获取账户信息**

**接口描述**：

* 请求路径：`/api/config`
* HTTP 方法：`GET`

**调用代码**：

```go
func main() {
	response, err := sendRequest("GET", "/api/config")
	if err != nil {
		fmt.Println("请求失败：", err)
		return
	}
	fmt.Println("账户信息：", string(response))
}
```

***

**5.2 创建订单**

**接口描述**：

* 请求路径：`/api/order?quantity=65000&target_address=TRON_ADDRESS&period=1`
* HTTP 方法：`POST`

**调用代码**：

```go
func main() {
	requestPath := "/api/order?quantity=65000&target_address=TRON_ADDRESS&period=1"
	response, err := sendRequest("POST", requestPath)
	if err != nil {
		fmt.Println("请求失败：", err)
		return
	}
	fmt.Println("订单已创建：", string(response))
}
```

***

**5.3 查询订单状态**

**接口描述**：

* 请求路径：`/api/order/{pay_hash}`
* HTTP 方法：`GET`

**调用代码**：

```go
func main() {
	payHash := "abcd1234" // 替换为实际的 pay_hash
	requestPath := fmt.Sprintf("/api/order/%s", payHash)
	response, err := sendRequest("GET", requestPath)
	if err != nil {
		fmt.Println("请求失败：", err)
		return
	}
	fmt.Println("订单状态：", string(response))
}
```

***

#### **6. 常见问题**

**6.1 签名无效 (401 Unauthorized)**

* 确认 `MF-ACCESS-KEY` 是否正确。
* 确保签名按照规则生成：
  * 拼接顺序为：`timestamp + method + requestPath`。
  * 时间戳格式是否为 UTC。
  * 使用正确的 `SECRET_KEY`。

**6.2 请求参数错误 (400 Bad Request)**

* 检查请求路径是否正确，尤其是查询参数是否完整。
* 确认 `Content-Type` 是否为 `application/json`。

**6.3 请求频率限制 (429 Too Many Requests)**

* 添加合理的请求间隔（例如每秒最多 2 次请求）。

***

#### **7. 总结**

通过本指南，您可以使用 **Go语言** 调用 Mefree.NET API，包括生成签名、构建请求以及解析响应数据。建议为重要操作（如订单创建）添加重试机制，提高调用可靠性。如有问题，请联系 Mefree 官方支持团队。


---

# Agent Instructions: 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:

```
GET https://docs.mefree.net/zh/getting-started/how-to-buy-energy/go.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
