乐趣区

关于javascript:web3-连接以太坊XverseUniSat钱包获取签名

连贯以太坊

这里是我是应用 Metamask 钱包连贯
MetaMask SDK

筹备工作

  1. 装置 SDK

    yarn add @metamask/sdk
    // or
    npm install @metamask/sdk
  2. 装置 ethers(我这里是间接引入 JS 文件)

     <!-- 会导出一个全局的变量: ethers -->
    <script src="https://cdn.ethers.io/scripts/ethers-v4.min.js"
     charset="utf-8"
     type="text/javascript">
    </script>

    编写逻辑

    // 1. 这里依照官网提供的代码引入 SDK
    import {MetaMaskSDK} from '@metamask/sdk'
    
    // 实例化
    const MMSDK = new MetaMaskSDK(options);
    const ethereum = MMSDK.getProvider();
    
    // 获取钱包地址, 没有装置钱包会提醒装置 MetaMask 钱包插件
    const accounts = await ethereum.request({method: 'eth_requestAccounts'})
    console.log(accounts, 'accounts')
    
    // 2. 获取签名和公钥
    const provider = new window.ethers.providers.Web3Provider(ethereum)
    const signer = provider.getSigner()
     const signature = await signer.signMessage(`${Number(new Date())}`)
     console.log('签名后果:', signature)
     const publicKey = await signer.getAddress()
     console.log('公钥(以太坊地址):', publicKey)

连贯 UniSat

这里是我是应用 UniSat 钱包连贯
Docs

编写逻辑(UniSat 文档很不错,我就不做过多解释了)

import {getAddress, signTransaction, signMessage} from 'sats-connect'
// 判断是否装置了 UniSat 钱包
const iUniSat = () => {if (typeof window.unisat === 'undefined') {
      // Element-ui Message 组件
    Message({
      type: 'error',
      dangerouslyUseHTMLString: true,
      duration: '20000',
      message: `
        Please install UniSat!
        <a style="text-decoration: underline; font-weight: bold" target="_blank" href='https://chrome.google.com/webstore/detail/unisat-wallet/ppbibelpcjmhbdihakflkdcoccbgbkpo'>Download</a>
      `
    })
    return false
  }
  return true
}

// 链接 UniSat 钱包
const connectUniSat = async () => {if (iUniSat()) {
    try {const accounts = await window.unisat.requestAccounts()
      console.log('链接胜利', accounts)
      const r = await window.unisat.getAccounts()
      console.log('钱包', r)
      const publicKey = await window.unisat.getPublicKey()
      console.log('公钥', publicKey)
      const sign = await window.unisat.signMessage(`${Number(new Date())}`)
      console.log('签名', sign)      
    } catch (err) {if (err.message) {Message.error(err.message)
      }
      console.log(err, 'err')
    }
  }
}

连贯 Xverse 钱包

Docs 连贯钱包局部能够参照文档,然而生成 PSBT 文档写的很烂,有些变量都不晓得哪里来的

筹备工作

  1. 装置 获取地址以及签名等 依赖包

    yarn add sats-connect
    // or
    npm install sats-connect
  2. 装置生成 Psbt 依赖包 (也能够用 npm

    yarn add @scure/base @scure/btc-signer

编写逻辑

  try {let addresses = []
    // 获取地址
    await getAddress({
      payload: {
          // 这两都要
        purposes: ['ordinals', 'payment'],
        message: 'Address for receiving Ordinals',
        network: {type: 'Testnet'}
      },
      onFinish: (response) => {
        addresses = response.addresses
        console.log('地址', addresses)
      },
      onCancel: () => {console.log('勾销')
      }
    })
  } catch (err) {console.log(err)
    // 没有装置钱包提醒去装置钱包
    if (err.message === 'No Bitcoin Wallet installed') {
      Message({
        type: 'error',
        dangerouslyUseHTMLString: true,
        duration: '20000',
        message: `
          No Bitcoin Wallet installed!
          <a style="text-decoration: underline; font-weight: bold" target="_blank" href='https://chrome.google.com/webstore/detail/xverse-wallet/idnnbdplmphpflfnlkomgpfbpcgelopg'>Download</a>
        `
      })
    }
  }

须要留神的是钱包中也要抉择为测试网

拿到地址数据后再获取地址代码前面增加生成签名代码


// await getAddress({
//...
// })
// 获取签名写在获取地址上面
 await signTransaction({
   payload: {
     network: {
         // 测试网 Testnet,主网 Mainnet。先用测试网测试
       type: 'Testnet'
     },
     message: 'Sign Transaction',
     // 调用生成 Psbt 函数
     psbtBase64: createPsbt(addresses),
     broadcast: false,
     inputsToSign: [
       {
           // 这里为 payment address. payment address 在获取的值的时候拿到
         address: addresses[1].address,
         signingIndexes: [0]
       }
     ]
   },
   onFinish: (response) => {
     data.signatureBase64 = response.psbtBase64
     console.log('签名', response)
   },
   onCancel: () => {console.log('sign cancel')
   }
 })

生成 Psbt。先把 Docs 文档地址代码 copy 过去。而后更改相应变量值

残缺代码如下:

const createPsbt = (addresses) => {
  // 文档上没有申明 tx 这里找了良久 tx 是什么
  const tx = new btc.Transaction()

  const bitcoinTestnet = {
    bech32: 'tb',
    pubKeyHash: 0x6f,
    scriptHash: 0xc4,
    wif: 0xef
  }

  const output = {
    tx_hash: 'f39d37ec885de70c598648a2f80f103e1cdf34f7021ddfcb22216b7076169226',
    block_height: 780179,
    tx_input_n: -1,
    tx_output_n: 1,
    value: 300000,
    ref_balance: 22681,
    spent: false,
    confirmations: 123,
    confirmed: '2023-03-10T10:02:21Z',
    double_spend: false
  }

  // addresses[1].publicKey 就是 payment publicKey,在获取地址时拿到
  const publicKey = hex.decode(addresses[1].publicKey)
  const p2wpkh = btc.p2wpkh(publicKey, bitcoinTestnet)
  const p2sh = btc.p2sh(p2wpkh, bitcoinTestnet)

  tx.addInput({
    txid: output.tx_hash,
    index: output.tx_output_n,
    witnessUtxo: {
      script: p2sh.script,
      amount: BigInt(output.value)
    },
    redeemScript: p2sh.redeemScript
  })

  const recipient = addresses[0].address
  const changeAddress = addresses[1].address

  tx.addOutputAddress(recipient, BigInt(200000), bitcoinTestnet)
  tx.addOutputAddress(changeAddress, BigInt(80000), bitcoinTestnet)

  const psbt = tx.toPSBT(0)
  const psbtB64 = base64.encode(psbt)

  return psbtB64
}

如果要改成 Mainnet 状况下,须要将获取地址 getAddress,signTransaction 中的 network 对象下 type 属性的值都改成 Mainnet。并且 bitcoinTestnet 变量也须要相应更改。

  const bitcoinTestnet = {
    bech32: 'bc',
    pubKeyHash: 0x00,
    scriptHash: 0x05,
    wif: 0x80
  }

以上就是 连贯以太坊、Xverse、UniSat 钱包并获取签名 全副代码了,心愿能够帮忙到有须要的小伙伴。

退出移动版