+ {JSON.stringify(attrs.object, null, 2)}
+```
+
+زیادہ تر فیلڈز [`JSON.stringify`](https://www.w3schools.com/js/js_json_stringify.asp) کا استعمال کرتے ہوئے دکھائے جاتے ہیں۔
+
+```tsx
+
+ { funs.length > 0 &&
+ <>
+ فنکشنز:
+ {message}
+ +{status}
+ + ++ {" "} + 🦊 + آپ کو اپنے براؤزر میں MetaMask، ایک ورچوئل Ethereum والیٹ، انسٹال کرنا ہوگا۔ + +
+ + ), + } + } +} +``` + +تو کوڈ کا یہ بڑا بلاک بالکل کیا کرتا ہے؟ + +پہلے، یہ چیک کرتا ہے کہ آیا آپ کے براؤزر میں `window.ethereum` فعال ہے۔ + +`window.ethereum` MetaMask اور دیگر والیٹ فراہم کنندگان کے ذریعے انجیکٹ کردہ ایک عالمی API ہے جو ویب سائٹس کو صارفین کے Ethereum اکاؤنٹس کی درخواست کرنے کی اجازت دیتا ہے۔ اگر منظور ہو جائے، تو یہ ان بلاک چینز سے ڈیٹا پڑھ سکتا ہے جن سے صارف جڑا ہوا ہے، اور صارف کو پیغامات اور ٹرانزیکشنز پر دستخط کرنے کا مشورہ دے سکتا ہے۔ مزید معلومات کے لیے [MetaMask دستاویزات](https://docs.metamask.io/guide/ethereum-provider.html#table-of-contents) دیکھیں! + +اگر `window.ethereum` موجود _نہیں_ ہے، تو اس کا مطلب ہے کہ MetaMask انسٹال نہیں ہے۔ اس کے نتیجے میں ایک JSON آبجیکٹ واپس کیا جاتا ہے، جہاں واپس کیا گیا `address` ایک خالی اسٹرنگ ہوتا ہے، اور `status` JSX آبجیکٹ یہ بتاتا ہے کہ صارف کو MetaMask انسٹال کرنا ہوگا۔ + +اب اگر `window.ethereum` موجود _ہے_، تو یہ وہ جگہ ہے جہاں چیزیں دلچسپ ہو جاتی ہیں۔ + +ایک try/catch لوپ کا استعمال کرتے ہوئے، ہم [`window.ethereum.request({ method: "eth_requestAccounts" });`](https://docs.metamask.io/guide/rpc-api.html#eth-requestaccounts) کو کال کرکے MetaMask سے جڑنے کی کوشش کریں گے۔ اس فنکشن کو کال کرنے سے براؤزر میں MetaMask کھل جائے گا، جس کے تحت صارف سے اپنے والیٹ کو آپ کے dApp سے جوڑنے کا کہا جائے گا۔ + +- اگر صارف جڑنے کا انتخاب کرتا ہے، تو `method: "eth_requestAccounts"` ایک سرنی واپس کرے گا جس میں صارف کے تمام اکاؤنٹ پتے شامل ہوں گے جو dapp سے جڑے ہوئے ہیں۔ مجموعی طور پر، ہمارا `connectWallet` فنکشن ایک JSON آبجیکٹ واپس کرے گا جس میں اس اری کا _پہلا_ `address` (لائن 9 دیکھیں) اور ایک `status` پیغام ہوگا جو صارف کو اسمارٹ کنٹریکٹ کے لیے ایک پیغام لکھنے کا کہے گا۔ +- اگر صارف کنکشن کو مسترد کر دیتا ہے، تو JSON آبجیکٹ میں واپس کیے گئے `address` کے لیے ایک خالی اسٹرنگ اور ایک `status` پیغام ہوگا جو یہ ظاہر کرے گا کہ صارف نے کنکشن کو مسترد کر دیا ہے۔ + +اب جب کہ ہم نے یہ `connectWallet` فنکشن لکھ لیا ہے، اگلا مرحلہ اسے اپنے `HelloWorld.js` جزو میں کال کرنا ہے۔ + +#### `connectWallet` فنکشن کو اپنے `HelloWorld.js` UI جزو میں شامل کریں {#add-the-connectWallet-function-to-your-HelloWorld-js-ui-component} + +`HelloWorld.js` میں `connectWalletPressed` فنکشن پر جائیں، اور اسے درج ذیل میں اپ ڈیٹ کریں: + +```javascript +// HelloWorld.js + +const connectWalletPressed = async () => { + const walletResponse = await connectWallet() + setStatus(walletResponse.status) + setWallet(walletResponse.address) +} +``` + +نوٹ کریں کہ ہماری زیادہ تر فعالیت `interact.js` فائل سے ہمارے `HelloWorld.js` جزو سے کس طرح تجرید کی گئی ہے؟ یہ اس لیے ہے تاکہ ہم M-V-C پیراڈائم کی تعمیل کریں! + +`connectWalletPressed` میں، ہم صرف اپنے امپورٹ کردہ `connectWallet` فنکشن پر ایک await کال کرتے ہیں، اور اس کے جواب کا استعمال کرتے ہوئے، ہم اپنے `status` اور `walletAddress` متغیرات کو ان کے اسٹیٹ ہکس کے ذریعے اپ ڈیٹ کرتے ہیں۔ + +اب، آئیے دونوں فائلیں (`HelloWorld.js` اور `interact.js`) محفوظ کریں اور اب تک اپنے UI کی جانچ کریں۔ + +[http://localhost:3000/](http://localhost:3000/) صفحے پر اپنا براؤزر کھولیں، اور صفحے کے اوپری دائیں کونے میں "والیٹ جوڑیں" بٹن دبائیں۔ + +اگر آپ نے MetaMask انسٹال کیا ہوا ہے، تو آپ سے اپنے والیٹ کو اپنے dApp سے جوڑنے کا کہا جائے گا۔ جڑنے کی دعوت قبول کریں۔ + +آپ کو دیکھنا چاہئے کہ والیٹ بٹن اب یہ ظاہر کرتا ہے کہ آپ کا پتہ جڑا ہوا ہے! بہت خوب 🔥 + +اگلا، صفحہ کو ریفریش کرنے کی کوشش کریں... یہ عجیب ہے۔ ہمارا والیٹ بٹن ہمیں MetaMask سے جڑنے کا کہہ رہا ہے، حالانکہ یہ پہلے سے ہی جڑا ہوا ہے... + +تاہم، کوئی خوف نہیں! ہم اسے آسانی سے حل کر سکتے ہیں (سمجھے؟) `getCurrentWalletConnected` کو نافذ کرکے، جو یہ چیک کرے گا کہ آیا کوئی پتہ پہلے سے ہی ہمارے dapp سے جڑا ہوا ہے اور ہمارے UI کو اسی کے مطابق اپ ڈیٹ کرے گا! + +#### `getCurrentWalletConnected` فنکشن {#the-getcurrentwalletconnected-function} + +`interact.js` فائل میں اپنے `getCurrentWalletConnected` فنکشن کو درج ذیل میں اپ ڈیٹ کریں: + +```javascript +// interact.js + +export const getCurrentWalletConnected = async () => { + if (window.ethereum) { + try { + const addressArray = await window.ethereum.request({ + method: "eth_accounts", + }) + if (addressArray.length > 0) { + return { + address: addressArray[0], + status: "👆🏽 اوپر ٹیکسٹ فیلڈ میں ایک پیغام لکھیں۔", + } + } else { + return { + address: "", + status: "🦊 اوپر دائیں بٹن کا استعمال کرتے ہوئے MetaMask سے جڑیں۔", + } + } + } catch (err) { + return { + address: "", + status: "😥 " + err.message, + } + } + } else { + return { + address: "", + status: ( + ++ {" "} + 🦊 + آپ کو اپنے براؤزر میں MetaMask، ایک ورچوئل Ethereum والیٹ، انسٹال کرنا ہوگا۔ + +
+ + ), + } + } +} +``` + +یہ کوڈ _بہت_ ملتا جلتا ہے `connectWallet` فنکشن سے جو ہم نے پچھلے مرحلے میں لکھا تھا۔ + +بنیادی فرق یہ ہے کہ `eth_requestAccounts` میتھڈ کو کال کرنے کے بجائے، جو صارف کے لیے اپنے والیٹ کو جوڑنے کے لیے MetaMask کھولتا ہے، یہاں ہم `eth_accounts` میتھڈ کو کال کرتے ہیں، جو صرف ایک اری واپس کرتا ہے جس میں فی الحال ہمارے dApp سے جڑے ہوئے MetaMask پتے ہوتے ہیں۔ + +اس فنکشن کو عمل میں دیکھنے کے لیے، آئیے اسے اپنے `HelloWorld.js` جزو کے `useEffect` فنکشن میں کال کریں: + +```javascript +// HelloWorld.js + +useEffect(async () => { + const message = await loadCurrentMessage() + setMessage(message) + addSmartContractListener() + + const { address, status } = await getCurrentWalletConnected() + setWallet(address) + setStatus(status) +}, []) +``` + +نوٹ کریں، ہم اپنے `walletAddress` اور `status` اسٹیٹ متغیرات کو اپ ڈیٹ کرنے کے لیے `getCurrentWalletConnected` پر اپنی کال کے جواب کا استعمال کرتے ہیں۔ + +اب جب کہ آپ نے یہ کوڈ شامل کر دیا ہے، آئیے اپنے براؤزر ونڈو کو ریفریش کرنے کی کوشش کریں۔ + +بہت اچھے! بٹن کو کہنا چاہیے کہ آپ جڑے ہوئے ہیں، اور آپ کے جڑے ہوئے والیٹ کے پتے کا ایک پیش نظارہ دکھانا چاہیے - یہاں تک کہ آپ کے ریفریش کرنے کے بعد بھی! + +#### `addWalletListener` نافذ کریں {#implement-addwalletlistener} + +ہمارے dApp والیٹ سیٹ اپ کا آخری مرحلہ والیٹ لسنر کو نافذ کرنا ہے تاکہ جب ہمارے والیٹ کی حالت تبدیل ہو تو ہمارا UI اپ ڈیٹ ہو، جیسے جب صارف منقطع ہوتا ہے یا اکاؤنٹس تبدیل کرتا ہے۔ + +اپنی `HelloWorld.js` فائل میں، اپنے `addWalletListener` فنکشن کو درج ذیل میں تبدیل کریں: + +```javascript +// HelloWorld.js + +function addWalletListener() { + if (window.ethereum) { + window.ethereum.on("accountsChanged", (accounts) => { + if (accounts.length > 0) { + setWallet(accounts[0]) + setStatus("👆🏽 اوپر ٹیکسٹ فیلڈ میں ایک پیغام لکھیں۔") + } else { + setWallet("") + setStatus("🦊 اوپر دائیں بٹن کا استعمال کرتے ہوئے MetaMask سے جڑیں۔") + } + }) + } else { + setStatus( ++ {" "} + 🦊 + آپ کو اپنے براؤزر میں MetaMask، ایک ورچوئل Ethereum والیٹ، انسٹال کرنا ہوگا۔ + +
+ ) + } +} +``` + +مجھے شرط ہے کہ آپ کو اس مقام پر کیا ہو رہا ہے یہ سمجھنے کے لیے ہماری مدد کی بھی ضرورت نہیں ہے، لیکن مکمل ہونے کی خاطر، آئیے اسے جلدی سے توڑتے ہیں: + +- سب سے پہلے، ہمارا فنکشن چیک کرتا ہے کہ آیا `window.ethereum` فعال ہے (یعنی، MetaMask انسٹال ہے)۔ + - اگر ایسا نہیں ہے، تو ہم صرف اپنے `status` اسٹیٹ متغیر کو ایک JSX اسٹرنگ پر سیٹ کرتے ہیں جو صارف کو MetaMask انسٹال کرنے کا کہتا ہے۔ + - اگر یہ فعال ہے، تو ہم لائن 3 پر لسنر `window.ethereum.on("accountsChanged")` سیٹ اپ کرتے ہیں جو MetaMask والیٹ میں اسٹیٹ تبدیلیوں کو سنتا ہے، جس میں یہ شامل ہے کہ جب صارف dApp سے ایک اضافی اکاؤنٹ جوڑتا ہے، اکاؤنٹس تبدیل کرتا ہے، یا ایک اکاؤنٹ منقطع کرتا ہے۔ اگر کم از کم ایک اکاؤنٹ جڑا ہوا ہے، تو `walletAddress` اسٹیٹ متغیر کو لسنر کے ذریعے واپس کیے گئے `accounts` اری میں پہلے اکاؤنٹ کے طور پر اپ ڈیٹ کیا جاتا ہے۔ ورنہ، `walletAddress` کو ایک خالی اسٹرنگ کے طور پر سیٹ کیا جاتا ہے۔ + +آخری لیکن کم از کم، ہمیں اسے اپنے `useEffect` فنکشن میں کال کرنا ہوگا: + +```javascript +// HelloWorld.js + +useEffect(async () => { + const message = await loadCurrentMessage() + setMessage(message) + addSmartContractListener() + + const { address, status } = await getCurrentWalletConnected() + setWallet(address) + setStatus(status) + + addWalletListener() +}, []) +``` + +اور بس! ہم نے کامیابی سے اپنی تمام والیٹ کی فعالیت کی پروگرامنگ مکمل کر لی ہے! اب اپنے آخری کام کی طرف: اپنے اسمارٹ کنٹریکٹ میں محفوظ پیغام کو اپ ڈیٹ کرنا! + +### مرحلہ 6: `updateMessage` فنکشن نافذ کریں {#step-6-implement-the-updateMessage-function} + +ٹھیک ہے فیم، ہم آخری مرحلے پر پہنچ گئے ہیں! اپنی `interact.js` فائل کے `updateMessage` میں، ہم درج ذیل کام کرنے جا رہے ہیں: + +1. یقینی بنائیں کہ وہ پیغام جسے ہم اپنے اسمارٹ رابطہ میں شائع کرنا چاہتے ہیں، درست ہے +2. MetaMask کا استعمال کرتے ہوئے اپنے ٹرانزیکشن پر دستخط کریں +3. اس فنکشن کو ہمارے `HelloWorld.js` فرنٹ اینڈ جزو سے کال کریں + +اس میں زیادہ وقت نہیں لگے گا؛ آئیے اس dapp کو مکمل کریں! + +#### ان پٹ کی خرابی کو ہینڈل کرنا {#input-error-handling} + +فطری طور پر، فنکشن کے آغاز میں کسی قسم کا ان پٹ ایرر ہینڈلنگ ہونا معنی خیز ہے۔ + +ہم چاہیں گے کہ ہمارا فنکشن جلد واپس آ جائے اگر کوئی MetaMask ایکسٹینشن انسٹال نہیں ہے، کوئی والیٹ جڑا ہوا نہیں ہے (یعنی، پاس کیا گیا `address` ایک خالی اسٹرنگ ہے)، یا `message` ایک خالی اسٹرنگ ہے۔ آئیے `updateMessage` میں درج ذیل ایرر ہینڈلنگ شامل کریں: + +```javascript +// interact.js + +export const updateMessage = async (address, message) => { + if (!window.ethereum || address === null) { + return { + status: + "💡 بلاک چین پر پیغام کو اپ ڈیٹ کرنے کے لیے اپنا MetaMask والیٹ جوڑیں۔", + } + } + + if (message.trim() === "") { + return { + status: "❌ آپ کا پیغام خالی اسٹرنگ نہیں ہو سکتا۔", + } + } +} +``` + +اب جب کہ اس میں مناسب ان پٹ ایرر ہینڈلنگ ہے، اب وقت آگیا ہے کہ MetaMask کے ذریعے ٹرانزیکشن پر دستخط کریں! + +#### ہمارے ٹرانزیکشن پر دستخط کرنا {#signing-our-transaction} + +اگر آپ پہلے سے ہی روایتی web3 Ethereum ٹرانزیکشنز کے ساتھ آرام دہ ہیں، تو جو کوڈ ہم اگلا لکھیں گے وہ بہت مانوس ہوگا۔ اپنے ان پٹ ایرر ہینڈلنگ کوڈ کے نیچے، `updateMessage` میں درج ذیل شامل کریں: + +```javascript +// interact.js + +//ٹرانزیکشن پیرامیٹرز سیٹ اپ کریں +const transactionParameters = { + to: contractAddress, // کنٹریکٹ کی اشاعت کے دوران کے علاوہ ضروری ہے۔ + from: address, // صارف کے فعال پتے سے مماثل ہونا چاہئے۔ + data: helloWorldContract.methods.update(message).encodeABI(), +} + +//ٹرانزیکشن پر دستخط کریں +try { + const txHash = await window.ethereum.request({ + method: "eth_sendTransaction", + params: [transactionParameters], + }) + return { + status: ( + + ✅{" "} + + Etherscan پر اپنے ٹرانزیکشن کی حیثیت دیکھیں! + +.env کو کمٹ نہ کریں! براہ کرم یقینی بنائیں کہ آپ اپنی .env فائل کسی کے ساتھ شیئر یا ظاہر نہ کریں، کیونکہ ایسا کرنے سے آپ اپنے رازوں پر سمجھوتہ کر رہے ہیں۔ اگر آپ ورژن کنٹرول استعمال کر رہے ہیں، تو اپنی .env کو gitignore فائل میں شامل کریں۔
+