Refactor ethereum sign-in helpers

This commit is contained in:
silverpill 2022-02-08 10:51:55 +00:00
parent 2c9182d50c
commit 901d788d49
6 changed files with 55 additions and 52 deletions

View file

@ -2,7 +2,7 @@ import { Signer } from "ethers"
import { TransactionResponse } from "@ethersproject/abstract-provider" import { TransactionResponse } from "@ethersproject/abstract-provider"
import { BACKEND_URL } from "@/constants" import { BACKEND_URL } from "@/constants"
import { Signature } from "@/utils/ethereum" import { EthereumSignature } from "@/utils/ethereum"
import { http } from "./common" import { http } from "./common"
import { Contracts, getContract } from "./contracts" import { Contracts, getContract } from "./contracts"
import { Post } from "./posts" import { Post } from "./posts"
@ -27,7 +27,7 @@ export async function makePermanent(
export async function getMintingAuthorization( export async function getMintingAuthorization(
authToken: string, authToken: string,
postId: string, postId: string,
): Promise<Signature> { ): Promise<EthereumSignature> {
const url = `${BACKEND_URL}/api/v1/statuses/${postId}/signature` const url = `${BACKEND_URL}/api/v1/statuses/${postId}/signature`
const response = await http(url, { const response = await http(url, {
method: "GET", method: "GET",
@ -53,7 +53,7 @@ export async function mintToken(
signer: Signer, signer: Signer,
ownerAddress: string, ownerAddress: string,
tokenUri: string, tokenUri: string,
serverSignature: Signature, serverSignature: EthereumSignature,
): Promise<TransactionResponse> { ): Promise<TransactionResponse> {
const adapter = await getContract(Contracts.Adapter, contractAddress, signer) const adapter = await getContract(Contracts.Adapter, contractAddress, signer)
const transaction = await adapter.mint( const transaction = await adapter.mint(

View file

@ -2,13 +2,13 @@ import { Signer } from "ethers"
import { TransactionResponse } from "@ethersproject/abstract-provider" import { TransactionResponse } from "@ethersproject/abstract-provider"
import { BACKEND_URL } from "@/constants" import { BACKEND_URL } from "@/constants"
import { Signature } from "@/utils/ethereum" import { EthereumSignature } from "@/utils/ethereum"
import { http } from "./common" import { http } from "./common"
import { Contracts, getContract } from "./contracts" import { Contracts, getContract } from "./contracts"
export async function getSubscriptionAuthorization( export async function getSubscriptionAuthorization(
authToken: string, authToken: string,
): Promise<Signature> { ): Promise<EthereumSignature> {
const url = `${BACKEND_URL}/api/v1/accounts/authorize_subscription` const url = `${BACKEND_URL}/api/v1/accounts/authorize_subscription`
const response = await http(url, { const response = await http(url, {
method: "GET", method: "GET",
@ -26,7 +26,7 @@ export async function configureSubscription(
contractAddress: string, contractAddress: string,
signer: Signer, signer: Signer,
recipientAddress: string, recipientAddress: string,
serverSignature: Signature, serverSignature: EthereumSignature,
): Promise<TransactionResponse> { ): Promise<TransactionResponse> {
const adapter = await getContract(Contracts.Adapter, contractAddress, signer) const adapter = await getContract(Contracts.Adapter, contractAddress, signer)
const transaction = await adapter.configureSubscription( const transaction = await adapter.configureSubscription(

View file

@ -226,7 +226,7 @@ import VisibilityIcon from "@/components/VisibilityIcon.vue"
import { useInstanceInfo } from "@/store/instance" import { useInstanceInfo } from "@/store/instance"
import { useCurrentUser } from "@/store/user" import { useCurrentUser } from "@/store/user"
import { CRYPTOCURRENCIES } from "@/utils/cryptocurrencies" import { CRYPTOCURRENCIES } from "@/utils/cryptocurrencies"
import { getSigner } from "@/utils/ethereum" import { getWallet } from "@/utils/ethereum"
import { formatDate } from "@/utils/format" import { formatDate } from "@/utils/format"
interface PaymentOption { interface PaymentOption {
@ -481,7 +481,7 @@ export default class PostComponent extends Vue {
this.isWaitingForToken = false this.isWaitingForToken = false
return return
} }
const signer = await getSigner() const signer = await getWallet()
if (!signer) { if (!signer) {
this.isWaitingForToken = false this.isWaitingForToken = false
return return

View file

@ -1,13 +1,13 @@
import { Signer } from "ethers" import { Signer } from "ethers"
import { Web3Provider } from "@ethersproject/providers" import { Web3Provider } from "@ethersproject/providers"
export function getProvider(): Web3Provider | null { export function getWeb3Provider(): Web3Provider {
const provider = (window as any).ethereum const provider = (window as any).ethereum
return new Web3Provider(provider) return new Web3Provider(provider)
} }
export async function getSigner(): Promise<Signer | null> { export async function getWallet(): Promise<Signer | null> {
const provider = getProvider() const provider = getWeb3Provider()
if (!provider) { if (!provider) {
return null return null
} }
@ -22,8 +22,39 @@ export async function getSigner(): Promise<Signer | null> {
return signer return signer
} }
export interface Signature { export interface EthereumSignature {
v: number; v: number;
r: string; r: string;
s: string; s: string;
} }
export async function getWalletAddress(provider: Web3Provider): Promise<string | null> {
let walletAddress
try {
[walletAddress] = await provider.send("eth_requestAccounts", [])
} catch (error) {
// Access denied
console.warn(error)
return null
}
return walletAddress.toLowerCase()
}
export async function getWalletSignature(
provider: Web3Provider,
walletAddress: string,
message: string,
): Promise<string | null> {
let signature
try {
signature = await provider.send(
"personal_sign",
[message, walletAddress],
)
} catch (error) {
// Signature request rejected
console.warn(error)
return null
}
return signature
}

View file

@ -52,14 +52,13 @@
<script lang="ts"> <script lang="ts">
import { Options, Vue, setup } from "vue-class-component" import { Options, Vue, setup } from "vue-class-component"
import { Web3Provider } from "@ethersproject/providers"
import { createUser, getAccessToken, getCurrentUser } from "@/api/users" import { createUser, getAccessToken, getCurrentUser } from "@/api/users"
import { InstanceInfo } from "@/api/instance" import { InstanceInfo } from "@/api/instance"
import Loader from "@/components/Loader.vue" import Loader from "@/components/Loader.vue"
import { useInstanceInfo } from "@/store/instance" import { useInstanceInfo } from "@/store/instance"
import { useCurrentUser } from "@/store/user" import { useCurrentUser } from "@/store/user"
import { getProvider } from "@/utils/ethereum" import { getWeb3Provider, getWalletAddress, getWalletSignature } from "@/utils/ethereum"
@Options({ @Options({
components: { Loader }, components: { Loader },
@ -82,45 +81,18 @@ export default class LandingPage extends Vue {
return this.store.instance return this.store.instance
} }
private async getWalletAddress(provider: Web3Provider): Promise<string | null> {
let walletAddress
try {
[walletAddress] = await provider.send("eth_requestAccounts", [])
} catch (error) {
// Access denied
console.warn(error)
return null
}
return walletAddress.toLowerCase()
}
private async getSignature(provider: Web3Provider, walletAddress: string, message: string): Promise<string | null> {
let signature
try {
signature = await provider.send(
"personal_sign",
[message, walletAddress],
)
} catch (error) {
// Signature request rejected
console.warn(error)
return null
}
return signature
}
async register() { async register() {
this.registrationErrorMessage = null this.registrationErrorMessage = null
const provider = getProvider() const provider = getWeb3Provider()
if (!provider || !this.store.instance) { if (!provider || !this.store.instance) {
return return
} }
const loginMessage = this.store.instance.login_message const loginMessage = this.store.instance.login_message
const walletAddress = await this.getWalletAddress(provider) const walletAddress = await getWalletAddress(provider)
if (!walletAddress) { if (!walletAddress) {
return return
} }
const signature = await this.getSignature(provider, walletAddress, loginMessage) const signature = await getWalletSignature(provider, walletAddress, loginMessage)
if (!signature) { if (!signature) {
return return
} }
@ -148,16 +120,16 @@ export default class LandingPage extends Vue {
async login() { async login() {
this.loginErrorMessage = null this.loginErrorMessage = null
const provider = getProvider() const provider = getWeb3Provider()
if (!provider || !this.store.instance) { if (!provider || !this.store.instance) {
return return
} }
const loginMessage = this.store.instance.login_message const loginMessage = this.store.instance.login_message
const walletAddress = await this.getWalletAddress(provider) const walletAddress = await getWalletAddress(provider)
if (!walletAddress) { if (!walletAddress) {
return return
} }
const signature = await this.getSignature(provider, walletAddress, loginMessage) const signature = await getWalletSignature(provider, walletAddress, loginMessage)
if (!signature) { if (!signature) {
return return
} }

View file

@ -150,7 +150,7 @@ import ProfileListItem from "@/components/ProfileListItem.vue"
import Sidebar from "@/components/Sidebar.vue" import Sidebar from "@/components/Sidebar.vue"
import { useInstanceInfo } from "@/store/instance" import { useInstanceInfo } from "@/store/instance"
import { useCurrentUser } from "@/store/user" import { useCurrentUser } from "@/store/user"
import { getSigner } from "@/utils/ethereum" import { getWallet } from "@/utils/ethereum"
@Options({ @Options({
components: { components: {
@ -306,7 +306,7 @@ export default class ProfileView extends Vue {
} }
async connectWallet() { async connectWallet() {
const signer = await getSigner() const signer = await getWallet()
if (!signer) { if (!signer) {
return return
} }
@ -329,7 +329,7 @@ export default class ProfileView extends Vue {
) { ) {
return return
} }
const signer = await getSigner() const signer = await getWallet()
if (!signer) { if (!signer) {
return return
} }
@ -350,7 +350,7 @@ export default class ProfileView extends Vue {
return return
} }
// Subscription configuration tx can be send from any address // Subscription configuration tx can be send from any address
const signer = await getSigner() const signer = await getWallet()
if (!signer) { if (!signer) {
return return
} }
@ -379,7 +379,7 @@ export default class ProfileView extends Vue {
) { ) {
return return
} }
const signer = await getSigner() const signer = await getWallet()
if (!signer) { if (!signer) {
return return
} }