连接以太坊
这里是我是使用 Metamask 钱包连接
MetaMask SDK
准备工作
安装
SDKyarn add @metamask/sdk // or npm install @metamask/sdk安装
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)// 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')
}
}
}</code></pre><h3 id="item-0-6">连接 <code>Xverse</code> 钱包</h3><p><a target="_blank" href="https://link.segmentfault.com/?enc=QhlLQwZFUS17v%2BtDvkdS5Q%3D%3D.hfQ7%2B3cHWxmirNm8%2BKk3d%2B0P8kP%2BPdeIUcIwhwzqKjE9pMzLITLaZSgPhnU7%2BT3GK2bpuIRzXUtQADdvUB4BdB8bXRnSc42EmwTaayzeq%2FA%3D"><strong>Docs</strong></a> 连接钱包部分可以参照文档,但是生成 <code>PSBT</code> 文档写的很烂,有些变量都不知道哪里来的</p><h3 id="item-0-7">准备工作</h3><ol><li><p>安装 获取地址以及签名等 依赖包</p><pre><code class="base">yarn add sats-connect
// or
npm install sats-connect</code></pre></li><li><p>安装生成 <code>Psbt 依赖包</code>(也可以用 <code>npm</code>)</p><pre><code class="base">yarn add @scure/base @scure/btc-signer</code></pre></li></ol><h3 id="item-0-8">编写逻辑</h3><pre><code class="js"> 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>
`
})
}
}</code></pre><p><strong><code>需要注意的是钱包中也要选择为测试网</code></strong><br></p><p>拿到地址数据后再获取地址代码后面添加生成签名代码</p><pre><code class="js">
// 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')
}
})</code></pre><p>生成 <code>Psbt</code>。 先把 <a target="_blank" href="https://link.segmentfault.com/?enc=yghIjALfyB0w2lzvRm1NAQ%3D%3D.3aqYOZNZhAU%2FG0E7qDjf4VQkc3YVBCHkZ9mlziwd5%2B3oqwvOUS7VnvCAbOWtZBHmEkAi80L5YWvealMnC%2FCABSILIU5uDeBOndJpHrgS2CHWzT78irojElC55%2Fb9PxyC9iCCAi1SOpJ25HZbyGArlufNxww3PRG3d9rlvpY1pws%3D">Docs</a> 文档地址代码 <code>copy</code> 过来。然后更改相应变量值<br><br>完整代码如下:</p><pre><code class="js">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
}</code></pre><p>如果要改成 <code>Mainnet</code> 情况下,需要将获取地址 <code>getAddress,signTransaction</code> 中的 <code>network</code> 对象下 <code>type</code> 属性的值都改成 <code>Mainnet</code>。并且 <code>bitcoinTestnet</code> 变量也需要相应更改。</p><pre><code class="js"> const bitcoinTestnet = {
bech32: 'bc',
pubKeyHash: 0x00,
scriptHash: 0x05,
wif: 0x80
}</code></pre><p>以上就是 <strong><code>连接以太坊、Xverse、UniSat钱包并获取签名</code></strong> 全部代码了,希望可以帮助到有需要的小伙伴。</p>