从Web2探索Coinbase的API教程

771 阅读6分钟

从Web2的起点探索Coinbase的API

对从哪里开始使用Web3感到困惑?John Vester展示了使用Coinbase开发者工具入门是多么容易。

早在1977年,我这个有抱负的音乐家在看完电影 "星球大战 "后就想学习钢琴。我的目标是学习如何演奏大家都在谈论的这部电影的主旋律,所以我买了乐谱。我们家有一架钢琴,那是我祖父母的礼物。

当我看到书页上所有的音符时,10岁版本的我很快就不知所措了。

我想也许我应该从更简单的东西开始,所以我开始在钢琴椅里面的纸张里翻找。然后我发现了这个非常酷的音符表模板,它完全适合在钢琴的琴键后面。我无法找到一个完全匹配的模板,但这里有一个例子。

这对我来说是一个游戏规则的改变。我把其他所有的音乐都扔回了钢琴凳,开始工作,学习如何演奏《星球大战》。在很短的时间内,我就学会了弹奏那首曲子(和钢琴),不需要任何课程。

这让我想知道为什么这样的 "模板 "不存在于生活的所有方面。

新技术的陷阱

新的语言、平台、框架和设计模式都有一个共同的要求--开发者接受和采用。更常见的是,大多数都有另一个共同的挑战:比预期的更陡峭的学习曲线。

对我来说,Web3目前正处于这种状态,尽管我在《从全栈开发者到Web3先锋》一书中已经通过了Web3的例子。

边缘开发者已经在用Web3做伟大的事情了。 但是,那些像我一样想要开始工作而不感到不知所措和沮丧的下一百万开发者怎么办?我们如何才能找到一种方法让他们加入到Web3中来呢?

我想为Web3开发找到一个辅助模板,当我开始探索Coinbase SDKs时,我发现了它。

Coinbase SDK/APIs

根据维基百科,Coinbase是一家美国上市公司,自2012年6月以来一直运营着一个加密货币交换平台。与我在Marqeta上所写的类似,Coinbase提供了一系列应用编程接口(API)和软件开发工具包(SDK),供那些对建立专注于数字货币的应用感兴趣的开发者使用。

Coinbase钱包SDK就是这样一个例子。

对于这份出版物,我想完成以下任务:

  • 使用React创建一个简单的Web3应用程序

  • 将我的钱包浏览器扩展与Dapp结合起来

  • 允许用户使用Coinbase钱包SDK进行捐赠

使用Coinbase钱包SDK创建一个Web3应用程序

为了开始,我们可以使用React CLI创建一个名为coinbase-wallet-example的React应用程序。

npx create-react-app coinbase-wallet-example

在创建了React应用程序后,我使用下面的命令改变到coinbase-wallet-example目录中。

cd coinbase-wallet-example

由于较新版本的create-react-app不再包括polyfills支持--这是正确使用web3.js的必要条件--这需要较老版本的react-scripts。

npm install --save-exact react-scripts@4.0.3

由于我们将建立一个Web3的例子,所以使用npm安装了web3框架(其他选项可以在这里找到)。

npm install web3

接下来,使用npm安装Coinbase Wallet SDK(其他选项可以在这里找到)。

npm install @coinbase/wallet-sdk

使用Infura区块链开发套件,我创建了一个名为coinbase-wallet-example 的新项目。

接下来,我切换到Ropsten测试网络,并注意到项目的密钥和URL。

现在,我们只需要包括以下代码来初始化Coinbase钱包SDK和一个Web3对象:

JavaScript

import CoinbaseWalletSDK from '@coinbase/wallet-sdk'
import Web3 from 'web3';

const APP_NAME = 'coinbase-wallet-example';
const APP_LOGO_URL = './coinbase-logo.png';
const DEFAULT_ETH_JSONRPC_URL = 'https://ropsten.infura.io/v3/56f … d69';
const DEFAULT_CHAIN_ID = 3; // 1=Ethereum (mainnet), 3=Ropsten, 5=Gorli

在我的应用程序的useEffect() 方法里面,我包含了必要的代码来初始化Coinbase钱包和Web3:

JavaScript

   const coinbaseWallet = new CoinbaseWalletSDK({
      appName: APP_NAME,
      appLogoUrl: APP_LOGO_URL,
    });

    const walletSDKProvider = coinbaseWallet.makeWeb3Provider(
        DEFAULT_ETH_JSONRPC_URL,
        DEFAULT_CHAIN_ID
    );

   const web3 = new Web3(walletSDKProvider);

对于这个非常简单的例子,我们将不利用智能合约,而是提供一个目标地址来发送捐款。

const DONATION_ADDRESS = '0x7 ... c94';

为了降低风险,代码将被更新,将DONATION_ADDRESS设置为使用中的钱包的连接地址。

DONATION_ADDRESS = account;

这基本上意味着代码将向发送者发送资金,只留下汽油费从用户的钱包中提取。React Dapp将允许用户连接他们的钱包,然后提供一个捐款数额(使用WEI单位),然后按下捐赠按钮,将资金发送到DONATION_ADDRESS。

这个简单的Dapp的完整源代码在下面注明。

JavaScript

import React, { useEffect, useState } from 'react';
import './App.css';
import CoinbaseWalletSDK from '@coinbase/wallet-sdk'
import Web3 from 'web3';

const APP_NAME = 'coinbase-wallet-example';
const APP_LOGO_URL = './coinbase-logo.png';
const DEFAULT_ETH_JSONRPC_URL = 'https://ropsten.infura.io/v3/56f ... d69';
const DEFAULT_CHAIN_ID = 3; // 1=Ethereum (mainnet), 3=Ropsten, 5=Gorli
const DEFAULT_ETHEREUM_CHAIN_ID = '0x3'; // Should match DEFAULT_CHAIN_ID above, but with leading 0x

let DONATION_ADDRESS = '0x7 ... c94'; // Target donation address goes here, just as a simple example

const App = () => {
  const [isWalletConnected, setIsWalletConnected] = useState(false);
  const [account, setAccount] = useState();
  const [walletSDKProvider, setWalletSDKProvider] = useState();
  const [web3, setWeb3] = useState();
  const [responseMessage, setResponseMessage] = useState();

  useEffect(() => {
    const coinbaseWallet = new CoinbaseWalletSDK({
      appName: APP_NAME,
      appLogoUrl: APP_LOGO_URL,
    });

    const walletSDKProvider = coinbaseWallet.makeWeb3Provider(
        DEFAULT_ETH_JSONRPC_URL,
        DEFAULT_CHAIN_ID
    );

    setWalletSDKProvider(walletSDKProvider);

    const web3 = new Web3(walletSDKProvider);
    setWeb3(web3);
  }, []);

  const checkIfWalletIsConnected = () => {
    if (!window.ethereum) {
      console.log(
          'No ethereum object found. Please install Coinbase Wallet extension or similar.'
      );

      web3.setProvider(walletSDKProvider.enable());

      return;
    }

    console.log('Found the ethereum object:', window.ethereum);

    connectWallet();
  };

  const connectWallet = async () => {
    const accounts = await window.ethereum.request({
      method: 'eth_requestAccounts',
    });

    if (!accounts.length) {
      console.log('No authorized account found');
      return;
    }

    if (accounts.length) {
      const account = accounts[0];
      console.log('Found an authorized account:', account);
      setAccount(account);

      try {
        await window.ethereum.request({
          method: 'wallet_switchEthereumChain',
          params: [{ chainId: DEFAULT_ETHEREUM_CHAIN_ID }],
        });
        console.log('Successfully switched to Ropsten Network');
      } catch (error) {
        console.error(error);
      }
    }

    setIsWalletConnected(true);
  };

  const donate = async () => {
    if (!account || !window.ethereum) {
      console.log('Wallet is not connected');
      return;
    }

    // For this simple example, make the DONATION_ADDRESS the user's address (send to themselves)
    DONATION_ADDRESS = account;

    const donationAmount = document.querySelector('#donationAmount').value;

    web3.eth.sendTransaction({
      from: account,
      to: DONATION_ADDRESS,
      value: donationAmount
    }, function(err, transactionHash) {
      if (!err) {
        setResponseMessage(transactionHash + ' success');
        console.log(transactionHash + " success");
      } else {
        console.error(err);
      }
    });
  };

  return (
    <div className="App">
      <header className="App-header">
        <img src={APP_LOGO_URL} className="App-logo" alt="logo" />
        {isWalletConnected ? (
            <>
              <h4>Donate some funds to yourself</h4>
              <p>Connected Account: {account}</p>
              <div>
                <input
                    type="number"
                    id="donationAmount"
                    defaultValue={1.00}
                />
                <label htmlFor="donationAmount">WEI</label>
                <button onClick={donate} id="donate" type="button">
                  Donate
                </button>
              </div>
            </>
        ) : (
            <button onClick={checkIfWalletIsConnected} id="connect" type="button">
              Connect Wallet
            </button>
        )}
        <p>{responseMessage}</p>
      </header>
    </div>
  );
}

export default App;

运行基于React的Dapp就像使用以下命令一样容易。

npm start

这里是一个例子,作为一个链接--因为我似乎无法让嵌入的GIF工作。

总结

自2021年以来,我一直在努力遵循以下使命宣言,我觉得它可以适用于任何IT专业人士。

"将你的时间集中在提供特性/功能上,以扩大你的知识产权的价值。充分利用框架、产品和服务来处理其他事情。

- J. Vester

我在介绍中提到的便条图模板变成了我生命中的一个关键点。这个藏在我们钢琴椅里的隐秘宝物不仅使我有能力演奏《星球大战》的主题,而且使我演奏音乐的能力突飞猛进。这个简单的模板和对学习的渴望最终为我进入伯克利音乐学院和参与一些音乐作品的能力铺平了道路。

Coinbase的API和SDK--或称开发者工具--为渴望在新兴的Web3世界中起步的开发者提供了一个类似的目的。开发人员可以将这些模块纳入他们的应用程序,并迅速入门,而不会被细节所困扰。

在这两种情况下,音符图模板和Coinbase开发者工具都坚持了我的使命宣言,允许个人继续专注于他们的主要目标--要么第一次学习弹钢琴,要么用Web3做一些很酷的事情。

如果你对本出版物的源代码感兴趣,你可以在GitLab上找到它,地址如下:

gitlab.com/johnjvester…

祝你今天过得非常愉快!