# Creating Vault account {"message":"Unauthorized user","code":1040} error

**URL:** <https://community.fireblocks.com/t/creating-vault-account-message-unauthorized-user-code-1040-error/1025>\
**Category:** Developer Discussion\
**Created:** [May 12, 2024, 10:14pm UTC](https://community.fireblocks.com/t/creating-vault-account-message-unauthorized-user-code-1040-error/1025 "2024-05-12T22:14:39Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![kjasuquo](https://avatars.discourse-cdn.com/v4/letter/k/c37758/32.png) [@kjasuquo](https://community.fireblocks.com/u/kjasuquo)\
**Post date:** [May 12, 2024, 10:14pm UTC](https://community.fireblocks.com/t/creating-vault-account-message-unauthorized-user-code-1040-error/1025/1 "2024-05-12T22:14:39Z")

</div>

With this setup, I am getting an unauthorized user error when trying to create a vault account with my key and secret. Why? And how can I correct it?

```auto
type ApiTokenProvider struct {
	privateKey *rsa.PrivateKey
	apiKey string
}

func NewApiTokenProvider(privateKeyPath, apiKey string) (*ApiTokenProvider, error) {
	privateKeyBytes, err := os.ReadFile(privateKeyPath)
	if err != nil {
		return nil, fmt.Errorf("error reading private key from %s: %w", privateKeyPath, err)
	}

	privateKey, err := jwt.ParseRSAPrivateKeyFromPEM(privateKeyBytes)
	if err != nil {
		return nil, fmt.Errorf("error parsing RSA private key: %w", err)
	}

	return &ApiTokenProvider{
		privateKey: privateKey,
		apiKey: apiKey,
	}, nil
}

func (a *ApiTokenProvider) SignJwt(path string, bodyJson interface{}) (string, error) {
	nonce := uuid.New().String()
	now := time.Now().Unix()
	expiration := now + 55 // Consider making this configurable

	bodyBytes, err := json.Marshal(bodyJson)
	if err != nil {
		return "", fmt.Errorf("error marshaling JSON: %w", err)
	}

	h := sha256.New()
	h.Write(bodyBytes)
	hashed := h.Sum(nil)

	claims := jwt.MapClaims{
		"uri": path,
		"nonce": nonce,
		"iat": now,
		"exp": expiration,
		"sub": a.apiKey,
		"bodyHash": hex.EncodeToString(hashed),
	}

	token := jwt.NewWithClaims(jwt.SigningMethodRS256, claims)
	tokenString, err := token.SignedString(a.privateKey)
	if err != nil {
		return "", fmt.Errorf("error signing token: %w", err)
	}

	return tokenString, nil
}

var httpClient = &http.Client{} // Reuse HTTP client

func makeAPIRequest(method, path string, body interface{}, tokenProvider *ApiTokenProvider) ([]byte, error) {
	var url = "https://sandbox-api.fireblocks.io" + path

	var reqBodyBytes []byte
	if body != nil {
		var err error
		reqBodyBytes, err = json.Marshal(body)
		if err != nil {
			return nil, fmt.Errorf("error marshaling request body: %w", err)
		}
	}

	token, err := tokenProvider.SignJwt(path, body)
	if err != nil {
		return nil, fmt.Errorf("error signing JWT: %w", err)
	}

	req, err := http.NewRequest(method, url, bytes.NewBuffer(reqBodyBytes))
	if err != nil {
		return nil, fmt.Errorf("error creating HTTP request: %w", err)
	}

	if method == "POST" {
		req.Header.Set("Content-Type", "application/json")
	}

	log.Println("the token: ", token)

	req.Header.Set("Authorization", "Bearer "+token)
	req.Header.Set("X-API-KEY", tokenProvider.apiKey)

	resp, err := httpClient.Do(req)
	if err != nil {
		return nil, fmt.Errorf("error sending HTTP request: %w", err)
	}
	defer resp.Body.Close()

	respBody, err := io.ReadAll(resp.Body)
	if err != nil {
		return nil, fmt.Errorf("error reading response body: %w", err)
	}

	return respBody, nil
}

// createAccount makes a POST request to create a new account
func createAccount(tokenProvider *ApiTokenProvider) error {
	path := "/v1/vault/accounts"
	body := map[string]interface{}{
		"name": "MyGoVault",
		"hiddenOnUI": false,
		"customerRefId": "testing-123",
		"autoFuel": true,
	}

	respBody, err := makeAPIRequest("POST", path, body, tokenProvider)
	if err != nil {
		return fmt.Errorf("error making POST request to create account: %w", err)
	}

	fmt.Printf("Response body for createAccount: %s\n", string(respBody))
	return nil
}

```

---

<div class="post-metadata">

**Author:** ![SlavaSereb](https://avatars.discourse-cdn.com/v4/letter/s/dfb087/32.png) [@SlavaSereb](https://community.fireblocks.com/u/SlavaSereb)\
**Post date:** [May 13, 2024, 2:23pm UTC](https://community.fireblocks.com/t/creating-vault-account-message-unauthorized-user-code-1040-error/1025/2 "2024-05-13T14:23:19Z")

</div>

Hey @kjasuquo can you please share the first 5 chars of your API key?

---

<div class="post-metadata">

**Author:** ![kjasuquo](https://avatars.discourse-cdn.com/v4/letter/k/c37758/32.png) [@kjasuquo](https://community.fireblocks.com/u/kjasuquo)\
**Post date:** [May 13, 2024, 2:36pm UTC](https://community.fireblocks.com/t/creating-vault-account-message-unauthorized-user-code-1040-error/1025/3 "2024-05-13T14:36:39Z")

</div>

Hi @SlavaSereb here you go `54619`

---

<div class="post-metadata">

**Author:** ![SlavaSereb](https://avatars.discourse-cdn.com/v4/letter/s/dfb087/32.png) [@SlavaSereb](https://community.fireblocks.com/u/SlavaSereb)\
**Post date:** [May 13, 2024, 2:54pm UTC](https://community.fireblocks.com/t/creating-vault-account-message-unauthorized-user-code-1040-error/1025/4 "2024-05-13T14:54:50Z")

</div>

Hey @kjasuquo,

I can see that this API key has the “NCW\_ADMIN” role which is not allowed to create vault accounts in your workspace but only Non Custodial Wallets.

For creating Vault Accounts (Self Custodial Wallets), you need to have either EDITOR or NON\_SIGNING\_ADMIN roles.

Let me know if you have any further questions.

---

<div class="post-metadata">

**Author:** ![kjasuquo](https://avatars.discourse-cdn.com/v4/letter/k/c37758/32.png) [@kjasuquo](https://community.fireblocks.com/u/kjasuquo)\
**Post date:** [May 15, 2024, 9:09am UTC](https://community.fireblocks.com/t/creating-vault-account-message-unauthorized-user-code-1040-error/1025/5 "2024-05-15T09:09:22Z")

</div>

Thank you @SlavaSereb but I still have a blocker.  
I have used it for NCW wallet and it works  
but I called the endpoint `/v1/wallets/{walletId}/setup_status` it gives me a response of `{"status":"INCOMPLETE","deviceSetupStatus":[]}`

For more context I called the add-asset endpoint `/v1/ncw/wallets/{walletId}/accounts/{accountId}/assets/BTC_TEST"` to add an asset to my created account and wallet and I got the response `{"message":"Wallet setup is incomplete","code":1000}`

Please what is missing and what can I do?

can you share with me the docs or how to complete the the wallet set\_up in order to enable me add assets?

---

<div class="post-metadata">

**Author:** ![kjasuquo](https://avatars.discourse-cdn.com/v4/letter/k/c37758/32.png) [@kjasuquo](https://community.fireblocks.com/u/kjasuquo)\
**Post date:** [May 16, 2024, 9:30am UTC](https://community.fireblocks.com/t/creating-vault-account-message-unauthorized-user-code-1040-error/1025/6 "2024-05-16T09:30:55Z")

</div>

while you respond, Please can you help me with the go-SDK for fireblocks?  
or is there a http endpoint for generating MPC Key for NCW Wallets? Please share @SlavaSereb

---

<div class="post-metadata">

**Author:** ![SlavaSereb](https://avatars.discourse-cdn.com/v4/letter/s/dfb087/32.png) [@SlavaSereb](https://community.fireblocks.com/u/SlavaSereb)\
**Post date:** [May 22, 2024, 6:16pm UTC](https://community.fireblocks.com/t/creating-vault-account-message-unauthorized-user-code-1040-error/1025/7 "2024-05-22T18:16:57Z")

</div>

Hey @kjasuquo

Sorry for the delayed response here.

Generating an MPC key for your Non Custodial Wallets is an essential part of the process.

You can check the step by step process of initializing our Web/Mobile SDKs with detailed explanation about every step in here:

> **[NCW - Fireblocks Embedded Wallet Solution](https://ncw-developers.fireblocks.com/docs/getting-started)**
>
> NCW - Fireblocks Embedded Wallet Solution

The API reference for the NCW SDK can be found here:

> **[Create a new wallet](https://developers.fireblocks.com/reference/create-1)**
>
> Create new Non Custodial Wallet

---

<div class="post-metadata">

**Author:** ![kjasuquo](https://avatars.discourse-cdn.com/v4/letter/k/c37758/32.png) [@kjasuquo](https://community.fireblocks.com/u/kjasuquo)\
**Post date:** [May 24, 2024, 7:16am UTC](https://community.fireblocks.com/t/creating-vault-account-message-unauthorized-user-code-1040-error/1025/9 "2024-05-24T07:16:47Z")

</div>

Hi @SlavaSereb I have generated the MPC key and I got this…

```auto
{"method":"get_service_certificates","headers":{"sdkVersion":"12.1.2","mpcVersion":6,"physicalDeviceId":"12ade3da-45a8-4dd8-8103-73f1604cd412","platformType":"Web"},"params":[{"names":["nckms","signing_service","zona_service","policy_service"]}]}

```

from the docs I need to make a call verify it or something like that `POST/v1/ncw/wallets/{walletID}/devices/{deviceID}/invoke msg`

Here is my code snippet

```auto
func makeAPIRequest(method, path string, body interface{}, tokenProvider *ApiTokenProvider) ([]byte, error) {
	var url = "https://sandbox-api.fireblocks.io" + path

	var reqBodyBytes []byte
	if body != nil {
		var err error
		reqBodyBytes, err = json.Marshal(body)
		if err != nil {
			return nil, fmt.Errorf("error marshaling request body: %w", err)
		}
	}

	token, err := tokenProvider.SignJwt(path, body)
	if err != nil {
		return nil, fmt.Errorf("error signing JWT: %w", err)
	}

	req, err := http.NewRequest(method, url, bytes.NewBuffer(reqBodyBytes))
	if err != nil {
		return nil, fmt.Errorf("error creating HTTP request: %w", err)
	}

	if method == "POST" {
		req.Header.Set("Content-Type", "application/json")
	}

	req.Header.Set("Authorization", "Bearer "+token)
	req.Header.Set("X-API-KEY", tokenProvider.apiKey)

	resp, err := httpClient.Do(req)
	if err != nil {
		return nil, fmt.Errorf("error sending HTTP request: %w", err)
	}
	defer resp.Body.Close()

	respBody, err := io.ReadAll(resp.Body)
	if err != nil {
		return nil, fmt.Errorf("error reading response body: %w", err)
	}

	return respBody, nil
}

type RequestPayload struct {
	Method string `json:"method"`
	Headers map[string]string `json:"headers"`
	Params []map[string][]string `json:"params"`
}

func verifyMPCKeys(tokenProvider *ApiTokenProvider, walletID, deviceID string) ([]byte, error) {
	path := "/v1/ncw/wallets/" + walletID + "/devices/" + deviceID + "/invoke"

	msg := RequestPayload{
		Method: "get_service_certificates",
		Headers: map[string]string{
			"sdkVersion": "12.1.2",
			"mpcVersion": "6",
			"physicalDeviceId": "12ade3da-45a8-4dd8-8103-73f1604cd412",
			"platformType": "Web",
		},
		Params: []map[string][]string{
			{
				"names": {"nckms", "signing_service", "zona_service", "policy_service"},
			},
		},
	}

	return makeAPIRequest("POST", path, msg, tokenProvider)
}

```

But I am getting this error message

```auto
{"error":"Bad Request","message":"Couldn't complete the operation. Please contact support if the problem persists."}

```

What am I doing wrong?
