[NEXTJS] 암호화폐 지갑 생성하기

BLOCKSDK·2023년 12월 18일
0
post-thumbnail

암호화폐 지갑은 블록체인에서 자금에 액세스하고 관리할 수 있는 인터페이스입니다.
보유하고 있는 암호화폐의 양을 보여주며 블록체인과 통신하여 디지털 자산을 주고 받을 수 있습니다.
암호화폐 거래, DeFi 플랫폼 또는 NFT를 이용하려면 암호화 지갑이 필요합니다.
이번 튜토리얼에서는 BLOCKSDK API, Next.js 프레임워크, 암호화폐 지갑을 생성합니다.

1. 프로젝트 설치 & BLOCSDK API 코드 발급

git clone https://github.com/Block-Chen/nextjs_wallet_demo.git

BLOCKSDK 홈페이지에 회원가입하여 WEB3 API 토큰 발급

2. 디렉토리 구조

├── src/app
├── api //api 목록
│   └── wallet
│       ├── balance
│       ├── create
│       ├── erc20
│       ├── erc721
│       ├── erc1155
│       └── list
├── wallet //페이지 목록
│   ├── balance
│   ├── create
│   ├── send
│   └── page.tsx
└── page.tsx

3. 개발 서버 열기

npm i && npm run dev

npm run build : Nextjs 어플리케이션을 빌드한다.
npm run start : build로 생성된 빌드 파일을 사용하여 어플리케이션을 실행한다.
npm run dev : Next.js 애플리케이션을 개발 환경에서 실행한다.
개발 모드에서는 페이지가 변경될 때마다 자동으로 빌드되어 브라우저에서 새로고침된다.
또한 정적 파일들이 요청될 때마다 다시 생성되어 더 빠른 개발을 가능하게 한다.

4. env파일 설정

NEXT_PUBLIC_BLOCKSDK_TOKEN     // blocksdk api 토큰
NEXT_PUBLIC_URL                // WEB3 테스트넷 or 메인넷 엔드포인트
NEXT_PUBLIC_NET                // 사용할 메인넷(eth,bsc,klay,matic)                        

5. 지갑 생성

생성할 지갑 이름을 입력하고 데이터를 전송하면 json형식으로 api에 전송합니다.
지갑 이름은 생성한 지갑 리스트에서 쉬운 구분을 위해 사용됩니다.

// /app/wallet/page.tsx
    async function onSubmit(event: FormEvent<HTMLFormElement>) {
        event.preventDefault()
        setIsLoading(true)
        setError(null) // Clear previous errors when a new request starts

        try {
          //body.name으로 지갑 이름 전달
            const response = await fetch('/api/wallet/create' , {
                method: 'POST',
                body: JSON.stringify({
                    name : body.name,
                }),
            }).then(response=>response.json()).then(data=>setData(data.data))

        } catch (error : any) {
            // Capture the error message to display to the user
            setError(error.message)
            console.error(error)
        } finally {
            setIsLoading(false)
        }
    }

지갑 생성 api에서 json형태로 받은 지갑이름을 가지고 BLOCKSDK API를 활용해 암호화폐 지갑을 생성합니다.
지갑 생성시 반환된 privatekey는 생성시에만 반환되니 저장해두셔야합니다.
당사에서는 privatekey를 저장하지 않으며 복구해드리지 않습니다.

// /app/api/wallet/create/route.tsx
import { NextResponse, NextRequest } from 'next/server';

//지갑 생성
export async function POST(request : NextRequest) {
    const { searchParams } = new URL(request.url)
    //.env에 설정한 정보를 호출
    const api_token = process.env.NEXT_PUBLIC_BLOCKSDK_TOKEN
    const url = process.env.NEXT_PUBLIC_URL as string
    const net = process.env.NEXT_PUBLIC_NET
    const payload = await request.json()
    const name = payload.get('name')

    //지갑 생성 API
    const res = await fetch(url + net + `/address?api_token=` + api_token, {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
        },
        body: JSON.stringify({ name: name }),
    })

    const data = await res.json()

    return NextResponse.json({data})
}

6. 생성한 지갑 리스트

지갑 생성을 통해 자신이 생성한 지갑목록을 확인할 수 있습니다.
지갑 생성과는 다르게 private_key가 반환되지 않습니다.

// /app/wallet/create/page.tsx
    async function onSubmit(event: FormEvent<HTMLFormElement>) {
        event.preventDefault()
        setIsLoading(true)
        setError(null) // Clear previous errors when a new request starts

        try {
            const formData = new FormData(event.currentTarget)
            //생성 지갑목록 호출
            const response = await fetch('/api/wallet/list' , {
                method: 'GET',
            }).then(response=>response.json()).then(data=>setData(data.data))

        } catch (error : any) {
            // Capture the error message to display to the user
            setError(error.message)
            console.error(error)
        } finally {
            setIsLoading(false)
        }
    }

.env에서 설정한 BLOCKSDK_TOKEN값을 이용하여 생성한 지갑 리스트가 반환됩니다.

// /app/api/wallet/list/route.tsx
import { NextResponse, NextRequest } from 'next/server';

//지갑 리스트
export async function GET(request : NextRequest) {
    const { searchParams } = new URL(request.url)
    const api_token = process.env.NEXT_PUBLIC_BLOCKSDK_TOKEN
    const url = process.env.NEXT_PUBLIC_URL as string
    const net = process.env.NEXT_PUBLIC_NET

    //생성한 지갑목록 호출
    const res = await fetch(url + net + `/address?api_token=` + api_token, {
        method: 'GET',
        headers: {
            'Content-Type': 'application/json',
        },
    });
    const data = await res.json();

    return NextResponse.json({ data })
}

7.지갑 잔액 확인

지갑의 소유중 코인을 확인할 수 있습니다.
메인넷 코인, erc20, nft에 대한 정보가 반환됩니다.
nft의 경우 erc721과 erc1155로 나뉘어져있습니다.
/app/wallet/balance/page.tsx, /app/wallet/erc20/page.tsx, /app/wallet/nft/page.tsx

    async function onSubmit(event: FormEvent<HTMLFormElement>) {
        event.preventDefault()
        setIsLoading(true)
        setError(null) // Clear previous errors when a new request starts

        try {
            const formData = new FormData(event.currentTarget)
            //입력된 지갑 주소로 api에서 지갑 조회
            const response = await fetch('/api/wallet/balance?&address=' + body.address , {
                method: 'GET',
            }).then(response=>response.json()).then(data=>setData(data.data))

        } catch (error : any) {
            // Capture the error message to display to the user
            setError(error.message)
            console.error(error)
        } finally {
            setIsLoading(false)
        }
    }

입력한 지갑의 코인 잔액에 대하여 반환해줍니다.

/app/api/wallet/balance/route.tsx, /app/api/wallet/erc20/route.tsx, /app/api/wallet/erc721/route.tsx, /app/api/wallet/erc721/route.tsx

export async function GET(request : NextRequest) {
    const { searchParams } = new URL(request.url)
    const api_token = process.env.NEXT_PUBLIC_BLOCKSDK_TOKEN
    const url = process.env.NEXT_PUBLIC_URL as string
    const net = process.env.NEXT_PUBLIC_NET
    const address = searchParams.get('address')

    const res = await fetch(url + net + `/address/`+ address +`/balance?api_token=` + api_token, {
        headers: {
            'Content-Type': 'application/json',
        },
    });
    const data = await res.json();

    return NextResponse.json({ data })
}

8.코인 전송

생성한 지갑의 privatekey값을 이용하여 소유한 코인을 전송할 수 있습니다.
erc20의 경우 전송할 erc20의 컨트랙트코드가 추가로 입력되어야합니다.
/app/wallet/send/page.tsx, /app/wallet/send/erc20/page.tsx

    async function onSubmit(event: FormEvent<HTMLFormElement>) {
        event.preventDefault()
        setIsLoading(true)
        setError(null) // Clear previous errors when a new request starts

        try {
            const formData = new FormData(event.currentTarget)
            const response = await fetch('/api/wallet/balance' , {
                method: 'POST',
                body: JSON.stringify({
                    from : body.from,
                    private_key : body.private_key,
                    to : body.to,
                    amount : body.amount,
                }),
            }).then(response=>response.json()).then(data=>setData(data.data))

        } catch (error : any) {
            // Capture the error message to display to the user
            setError(error.message)
            console.error(error)
        } finally {
            setIsLoading(false)
        }
    }

입력받은 지갑의 암호키와, 받는 사람, 보내는 사람, 보내는 코인 양을 이용하여 암호화폐를 전송합니다.
/app/api/wallet/balance/route.tsx, /app/api/wallet/erc20/route.tsx

export async function POST(request : NextRequest) {
    const { searchParams } = new URL(request.url)
    const api_token = process.env.NEXT_PUBLIC_BLOCKSDK_TOKEN
    const url = process.env.NEXT_PUBLIC_URL as string
    const net = process.env.NEXT_PUBLIC_NET
    const payload = await request.json()

    const res = await fetch(url + net + `/address/`+ payload.from +`/send?api_token=` + api_token, {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
        },
        body: JSON.stringify({
            private_key: payload.private_key,
            to : payload.to,
            amount : payload.amount,
        }),
    })

    const data = await res.json()

    return NextResponse.json({data})
}
profile
BLOCKSDK는 간편 코인 제작 기능 과 블록체인 서비스 개발을 단순화하여 블록체인에 전문화된 개발자 없이 빠르게 개발할수 있는 API 와 완성형 솔루션 제공 서비스입니다

0개의 댓글

관련 채용 정보