はじめに
Nuxt3がリリースされたので、@devprotocol/dev-kitと組み合わせて、DApp開発してみます。
環境
MacOSX 11.6 (Intel Mac)
Node.js v14.17.6
nuxt3 3.0.0-27324955.23397e6 (latest
指定)
@devprotocol/dev-kit 5.9.0
ethers 5.5.2
開発
インストール
Nuxt3や必要なパッケージをあらかじめインストールしておきます。
$ npx nuxi init nuxt3-app
$ cd nuxt3-app
$ yarn
$ yarn dev
http://localhost:3000 でアプリケーションが起動します。
TypeScript使うならこれ必要?(もしかしたら実行しなくてもいいかも)
$ yarn nuxi typecheck
その他必要なパッケージもインストール
$ yarn add ethers @devprotocol/dev-kit
アプリケーションを書いてみる
dev-kitのリポジトリにあるexamplesのget-property-info.jsを組み込んでみます。
特定のプロパティアドレスを指定して、その合計ステーキング数と報酬数(どちらも単位はDEV)を表示する感じです。
その他の前提としてはEthereumのmainnetを使うことにします。
app.vue
を以下のように変更します。(ソースコード内のコメントは後から追加しました。)
<template>
<div>
<NuxtWelcome />
</div>
</template>
<script>
import { ethers } from "ethers";
import { contractFactory, addresses } from "@devprotocol/dev-kit";
export default {
data() {
const config = useRuntimeConfig();
console.log(config, config.WEB3_PROVIDER_URL);
return {
config,
};
},
async mounted() {
// メインネットを使う
const provider = new ethers.providers.JsonRpcProvider(
this.config.WEB3_PROVIDER_URL
);
const network = await provider.ready;
console.log(network);
const contract = contractFactory(provider);
// 対象のプロパティアドレス
const propertyAddress = "0xac1AC9d00314aE7B4a7d6DbEE4860bECedF92309";
// コントラクトの準備
const registryContractAddress = addresses.eth.main.registry;
const lockupContractAddress = await contract
.registry(registryContractAddress)
.lockup();
// ステーキング数取得
const propertyStakingAmount = await contract
.lockup(lockupContractAddress)
.getPropertyValue(propertyAddress);
const stakingAmount = ethers.BigNumber.from(propertyStakingAmount).div(
new ethers.BigNumber.from(10).pow(18)
);
console.log(
`${propertyAddress}'s staking amount is ${stakingAmount.toBigInt()} DEV`
);
// 報酬数取得
const propertyRewards = await contract
.lockup(lockupContractAddress)
.calculateRewardAmount(propertyAddress);
const reward = ethers.BigNumber.from(propertyRewards[0]).div(
new ethers.BigNumber.from(10).pow(36)
);
console.log(`${propertyAddress}'s rewards is ${reward.toBigInt()} DEV`);
},
};
</script>
nuxt.config.ts
は以下
import { defineNuxtConfig } from "nuxt3";
// https://v3.nuxtjs.org/docs/directory-structure/nuxt.config
export default defineNuxtConfig({
build: {
transpile: ["@ethersproject", "ethers"],
},
publicRuntimeConfig: {
WEB3_PROVIDER_URL:
"https://eth-mainnet.alchemyapi.io/v2/XXXX",
},
});
https://eth-mainnet.alchemyapi.io/v2/XXXX
は自分で作成したAlchemyのキーとかローカルのEthereumノード使ってね。
で、起動するとエラー発生
Uncaught SyntaxError: import not found: default bignumber.js:9:7
nuxt.config.ts
を以下のようにvite.optimizeDeps
にエラーが発生しているパッケージを追加していく.
色々対応して別のエラーまで進んだ.
import { defineNuxtConfig } from "nuxt3";
// https://v3.nuxtjs.org/docs/directory-structure/nuxt.config
export default defineNuxtConfig({
build: {
transpile: ["@ethersproject", "ethers"],
},
vite: {
optimizeDeps: {
include: ["bn.js", "js-sha3", "hash.js", "aes-js", "scrypt-js", "bech32"],
},
},
publicRuntimeConfig: {
WEB3_PROVIDER_URL:
"https://eth-mainnet.alchemyapi.io/v2/XXXX",
},
});
ここまでで一旦 git init && git add XXX && git commit
しておく。
エラー解析からのさらに開発進める
もう一度起動してエラーの内容をみる.
Uncaught (in promise) TypeError: (intermediate value).BigNumber.from is not a constructor
なんと! new
不要だったのか!!このexamples私が追加したのですが、new
不要だったようです。
修正。
diff --git a/app.vue b/app.vue
index baf5fbd..2ecdda9 100644
--- a/app.vue
+++ b/app.vue
@@ -34,7 +34,7 @@ export default {
.lockup(lockupContractAddress)
.getPropertyValue(propertyAddress);
const stakingAmount = ethers.BigNumber.from(propertyStakingAmount).div(
- new ethers.BigNumber.from(10).pow(18)
+ ethers.BigNumber.from(10).pow(18)
);
console.log(
`${propertyAddress}'s staking amount is ${stakingAmount.toBigInt()} DEV`
@@ -44,7 +44,7 @@ export default {
.lockup(lockupContractAddress)
.calculateRewardAmount(propertyAddress);
const reward = ethers.BigNumber.from(propertyRewards[0]).div(
- new ethers.BigNumber.from(10).pow(36)
+ ethers.BigNumber.from(10).pow(36)
);
console.log(`${propertyAddress}'s rewards is ${reward.toBigInt()} DEV`);
},
うまく動いたっぽい!!
コンソールに出力されてる。
0xac1AC9d00314aE7B4a7d6DbEE4860bECedF92309's staking amount is 28645 DEV app.vue:40:13
0xac1AC9d00314aE7B4a7d6DbEE4860bECedF92309's rewards is 16377 DEV app.vue:50:3
最終調整
最後に表示を整える。最終的に以下のようなコードになった。
<template>
<div>
<p>property address: {{ propertyAddress }}</p>
<p>staking: {{ staking?.toBigInt() }} DEV</p>
<p>rewards: {{ reward?.toBigInt() }} DEV</p>
</div>
</template>
<script>
import { ethers } from "ethers";
import { contractFactory, addresses } from "@devprotocol/dev-kit";
export default {
data() {
const config = useRuntimeConfig();
console.log(config, config.WEB3_PROVIDER_URL);
return {
config,
propertyAddress: "0xac1AC9d00314aE7B4a7d6DbEE4860bECedF92309",
staking: undefined,
reward: undefined,
};
},
async mounted() {
// use main net
const registryContractAddress = addresses.eth.main.registry;
const provider = new ethers.providers.JsonRpcProvider(
this.config.WEB3_PROVIDER_URL
);
const network = await provider.ready;
console.log(network);
const contract = contractFactory(provider);
const lockupContractAddress = await contract
.registry(registryContractAddress)
.lockup();
const propertyStakingAmount = await contract
.lockup(lockupContractAddress)
.getPropertyValue(this.propertyAddress);
const stakingAmount = ethers.BigNumber.from(propertyStakingAmount).div(
ethers.BigNumber.from(10).pow(18)
);
console.log(
`${
this.propertyAddress
}'s staking amount is ${stakingAmount.toBigInt()} DEV`
);
const propertyRewards = await contract
.lockup(lockupContractAddress)
.calculateRewardAmount(this.propertyAddress);
const reward = ethers.BigNumber.from(propertyRewards[0]).div(
ethers.BigNumber.from(10).pow(36)
);
console.log(
`${this.propertyAddress}'s rewards is ${reward.toBigInt()} DEV`
);
this.staking = stakingAmount;
this.reward = reward;
},
};
</script>
でブラウザから見るとこんな感じ。
おわりに
Nuxt3でDApp開発できそうです。いい感じです。
以下リポジトリにソースコードがありますので、参考まで。