하아찡

[C#/WPF] Upbit프로젝트 Access 본문

C#/코인프로그램 - 코드

[C#/WPF] Upbit프로젝트 Access

하아찡 2023. 11. 27. 15:47

Access클래스는 업비트가 제공하는 OpenAPI를 사용하기위해 현재 사용자 API Key값이 등록이 되어있는지를 확인하고,

API Key값이 등록됐을때 API를 필요로 하는 기능들을 사용할 수 있게 해줌.

 

Access.cs

using FileIO;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Threading.Tasks;
using System.Windows;
using Upbit.Functions;

namespace Upbit.UpbitFunctions
{
    public class Access
    {

        public delegate void AccessEventHandler(bool connect);
        public static event AccessEventHandler CheckedAccess;

        private FncFileIO fileIO = new FncFileIO();

        private string KeyPath = "Access";
        private string KeyFile = "Key.txt";
        
        //키값
        private string Access_Key = "";
        private string Secret_Key = "";
        private bool _Access = false;
        private static Access instance;

        public static Access UpbitInstance
        {
            get
            {
                if (instance == null) instance = new Access();

                return instance;
            }
        }

        public Access()
        {
            
        }

        //해당 키 등록
        public void SetKeys(string Access, string Secret)
        {
            Access_Key = Access;
            Secret_Key = Secret;

            SaveKey(Access, Secret);

            //해당값이 True 경우에만 주문 계좌조회 등등 키가 필요한 작업들 실행가능
            _Access = CheckedKey();
            CheckedAccess(_Access);
        }

        private bool CheckedKey()
        {
            Task<bool> task = Task.Run(() => KeyCheck());
            bool accounts = task.Result;

            return accounts; 
        }
        public string GetAccessKey()
        {
            return Access_Key;
        }

        public string GetSecretKey()
        {
            return Secret_Key;
        }

        public void ExceptionKey()
        {
            _Access = false;
            CheckedAccess(_Access);
        }

        /// <summary>
        /// 키가 유무 체크 후 사용가능함 함수들 사용하기위해
        /// </summary>
        /// <returns></returns>
        public bool GetAccess()
        {
            bool keep = CheckedKey();
            if (_Access != keep)
            {
                _Access = keep;
                CheckedAccess(_Access);
            }
            return _Access;
        }

        /// <summary>
        /// 기존에 저장된 Key값들이 있을경우에 불러오는 함수
        /// </summary>
        /// <returns></returns>
        public void LoadKey()
        {
            FileIOAccess Keys  = fileIO.FileRead<FileIOAccess>(KeyPath, KeyFile);
            Access_Key = Keys.AccessKey is null ? "" : Keys.AccessKey;
            Secret_Key = Keys.SecretKey is null ? "" : Keys.SecretKey;

            _Access = CheckedKey();
            CheckedAccess(_Access);
        }

        /// <summary>
        /// 다이얼로그에서 키값을 등록하기위한 함수
        /// </summary>
        /// <param name="ac"></param>
        /// <param name="sc"></param>
        private void SaveKey(string ac, string sc)
        {
            FileIOAccess Keys = new FileIOAccess();
            Keys.SecretKey = sc;
            Keys.AccessKey = ac;
            fileIO.FileWrite(KeyPath, KeyFile, Keys);
        }


        public async Task<bool> KeyCheck()
        {
            URLs url = new URLs();
            bool ListResult;

            try
            {
                var client = new HttpClient();
                var request = new HttpRequestMessage
                {
                    Method = HttpMethod.Get,
                    RequestUri = new Uri(url.Account),
                    Headers =
                    {
                        { "accept", "application/json" },
                        { "Authorization", JWT.GetJWT() },
                    },
                };


                using (var response = await client.SendAsync(request))
                {
                    //response.EnsureSuccessStatusCode();
                    var body = await response.Content.ReadAsStringAsync();

                    JObject jmain = JObject.Parse(body);
                    JToken error = jmain.Value<JToken>("error");
                    string errorname = error.Value<string>("name");
                    Language.Lang.Upbit Lang = new Language.Lang.Upbit();
                    string KeyError = Lang.LKeyError;
                    string KeyComment = Lang.LKeyComment;
                    string PrintMessage = "";
                    if (errorname == "invalid_query_payload")        PrintMessage = "JWT 헤더의 페이로드가 올바르지 않습니다.";
                    else if (errorname == "jwt_verification") PrintMessage = "JWT 헤더 검증에 실패했습니다.";
                    else if (errorname == "expired_access_key") PrintMessage = "API 키가 만료되었습니다.";
                    else if (errorname == "nonce_used") PrintMessage = "이미 요청한 nonce값이 다시 사용되었습니다.";
                    else if (errorname == "no_authorization_i_p") PrintMessage = "허용되지 않은 IP 주소입니다.";
                    else if (errorname == "out_of_scope") PrintMessage = "허용되지 않은 기능입니다.";
                    MessageBox.Show(KeyError + "\n" + PrintMessage);
                    Logs.Loginstance.UpbitLog(PrintMessage);
                    return false;
                }
            }
            catch (Exception e)
            {
                return true;
                
            }


        }

    }
}

 

 

이벤트 생성

public delegate void AccessEventHandler(bool connect);
public static event AccessEventHandler CheckedAccess;

API Key값이 등록 혹은 잘못됐을경우 이벤트를 전달해주기위해 아래와같은 이벤트를 생성해줬습니다.

True로 값을 전달해줄경우 API Key값이 등록되어 제한된 기능을 풀어주는 이벤트를 발생시킵니다.

False는 반대로 이미 풀려있던 기능을 잠궈주는 이벤트로 발생합니다.

 

 

파일 저장 경로 및 파일명

private string KeyPath = "Access";
private string KeyFile = "Key.txt";

API Key값이 등록됐을경우 해당 키값을 저장하기위한 폴더명과 파일명을 지정해줌.

 

정상 키인지 확인

public async Task<bool> KeyCheck()
{
    URLs url = new URLs();
    bool ListResult;

    try
    {
        var client = new HttpClient();
        var request = new HttpRequestMessage
        {
            Method = HttpMethod.Get,
            RequestUri = new Uri(url.Account),
            Headers =
            {
                { "accept", "application/json" },
                { "Authorization", JWT.GetJWT() },
            },
        };


        using (var response = await client.SendAsync(request))
        {
            //response.EnsureSuccessStatusCode();
            var body = await response.Content.ReadAsStringAsync();

            JObject jmain = JObject.Parse(body);
            JToken error = jmain.Value<JToken>("error");
            string errorname = error.Value<string>("name");
            Language.Lang.Upbit Lang = new Language.Lang.Upbit();
            string KeyError = Lang.LKeyError;
            string KeyComment = Lang.LKeyComment;
            string PrintMessage = "";
            if (errorname == "invalid_query_payload")        PrintMessage = "JWT 헤더의 페이로드가 올바르지 않습니다.";
            else if (errorname == "jwt_verification") PrintMessage = "JWT 헤더 검증에 실패했습니다.";
            else if (errorname == "expired_access_key") PrintMessage = "API 키가 만료되었습니다.";
            else if (errorname == "nonce_used") PrintMessage = "이미 요청한 nonce값이 다시 사용되었습니다.";
            else if (errorname == "no_authorization_i_p") PrintMessage = "허용되지 않은 IP 주소입니다.";
            else if (errorname == "out_of_scope") PrintMessage = "허용되지 않은 기능입니다.";
            MessageBox.Show(KeyError + "\n" + PrintMessage);
            Logs.Loginstance.UpbitLog(PrintMessage);
            return false;
        }
    }
    catch (Exception e)
    {
        return true;
        
    }


}

급하게 추가하여 Language랑 연동을 안해놔서 추후에 수정해야함.

셋팅된 Key값을가지고 잔고를 확인시켜 값이 제대로 오는지 확인하여 키값이 정상작동하는지를 확인해줌.

데이터가 정상적으로 들어왔을때 catch쪽으로 넘어감으로 catch쪽에 true값을 반환하게 지정해줌.

대표적인 오류 코드는 UpbitAPI 가이드쪽을 확인해보시면 있습니다. 링크남겨드릴게요. 업비트오류코드

 

Open API | 업비트 개발자 센터

 

docs.upbit.com

 

 

키값 불러오기

public void LoadKey()
{
    FileIOAccess Keys  = fileIO.FileRead<FileIOAccess>(KeyPath, KeyFile);
    Access_Key = Keys.AccessKey is null ? "" : Keys.AccessKey;
    Secret_Key = Keys.SecretKey is null ? "" : Keys.SecretKey;

    _Access = CheckedKey();
    CheckedAccess(_Access);
}

파일에 저장된 Key값들이 있을경우 기능을 활성화 해주고 없을 경우 기능을 비활성화 해주는 이벤트를 발생시킴.

 

 

키값 저장

/// <summary>
/// 다이얼로그에서 키값을 등록하기위한 함수
/// </summary>
/// <param name="ac"></param>
/// <param name="sc"></param>
private void SaveKey(string ac, string sc)
{
    FileIOAccess Keys = new FileIOAccess();
    Keys.SecretKey = sc;
    Keys.AccessKey = ac;
    fileIO.FileWrite(KeyPath, KeyFile, Keys);
}

 

 

외부에서 Access가 됐는지 확인용

public bool GetAccess()
{
    bool keep = CheckedKey();
    if (_Access != keep)
    {
        _Access = keep;
        CheckedAccess(_Access);
    }
    return _Access;
}

 

반응형

'C# > 코인프로그램 - 코드' 카테고리의 다른 글

[C#/WPF] Upbit프로젝트 WebSocketTicker  (1) 2023.11.28
[C#/WPF] Upbit프로젝트 DialogAccess  (0) 2023.11.27
C# Network 프로젝트  (0) 2023.11.27
C# FileIO 프로젝트  (0) 2023.11.27
[C#/WPF] Language 프로젝트  (0) 2023.11.26