1
1
import { ethers } from 'ethers'
2
+ import { sign } from 'tweetnacl'
3
+ import { base58ToUint8Array , hexStringToUint8Array , strToHexStr , strToUtfBytes } from '../../../utils'
4
+ import * as flowTypes from '@onflow/types'
2
5
3
6
export interface UNInterface {
4
7
expiration : number
@@ -8,6 +11,7 @@ export interface UNInterface {
8
11
messageToSign : string
9
12
address ?: string
10
13
signature ?: string
14
+ blockchain ?: string
11
15
}
12
16
13
17
export class UN {
@@ -21,12 +25,73 @@ export class UN {
21
25
}
22
26
}
23
27
24
- public static recoverAddress ( un : UNInterface ) {
28
+ public static async verifySignature ( un : UNInterface ) {
25
29
if ( ! un . signature ) throw new Error ( 'Null signature' )
26
30
27
- const msgHash = ethers . utils . hashMessage ( un . messageToSign )
28
- const msgHashBytes = ethers . utils . arrayify ( msgHash )
29
- return ethers . utils . recoverAddress ( msgHashBytes , un . signature ) . toLowerCase ( )
31
+ if ( un . blockchain === 'solana' ) {
32
+ return await sign . detached . verify (
33
+ strToUtfBytes ( un . messageToSign ) ,
34
+ hexStringToUint8Array ( un . signature ) ,
35
+ base58ToUint8Array ( un . address ) ,
36
+ )
37
+ } else if ( un . blockchain === 'flow' ) {
38
+ const flowProvider = await import ( '../../../wallet/FlowProvider' )
39
+ const fcl = flowProvider . getFlowProvider ( )
40
+
41
+ try {
42
+ const response = await fcl
43
+ . send ( [
44
+ fcl . script `
45
+ pub fun main(address: Address, sig: String, msg: String): Bool {
46
+ let account = getAccount(address)
47
+ let sig = sig.decodeHex()
48
+ let msg = msg.decodeHex()
49
+ let isValid = false
50
+ var keyNumber = account.keys.count
51
+ var res: Bool = false
52
+ while keyNumber > 0 {
53
+ let accountKey = account.keys.get(keyIndex: Int(keyNumber - 1)) ?? panic("This keyIndex does not exist in this account")
54
+ let key = accountKey.publicKey
55
+ if key.verify(
56
+ signature: sig,
57
+ signedData: msg,
58
+ domainSeparationTag: "FLOW-V0.0-user",
59
+ hashAlgorithm: HashAlgorithm.SHA3_256
60
+ ) {
61
+ res = true
62
+ break
63
+ }
64
+ keyNumber = keyNumber - 1
65
+ }
66
+ return res
67
+ }
68
+ ` ,
69
+ fcl . args ( [
70
+ fcl . arg ( un . address , flowTypes . Address ) ,
71
+ fcl . arg ( un . signature , flowTypes . String ) ,
72
+ fcl . arg ( strToHexStr ( un . messageToSign ) , flowTypes . String ) ,
73
+ ] ) ,
74
+ ] )
75
+ . then ( fcl . decode )
76
+ if ( response ) {
77
+ return true
78
+ }
79
+ } catch ( e ) {
80
+ console . log ( 'Flow address recover error' )
81
+ }
82
+ return false
83
+ } else if ( ! un . blockchain || un . blockchain === 'evm' ) {
84
+ const msgHash = ethers . utils . hashMessage ( un . messageToSign )
85
+ const msgHashBytes = ethers . utils . arrayify ( msgHash )
86
+ let recoveredAddr = ethers . utils . recoverAddress ( msgHashBytes , un . signature ) . toLowerCase ( )
87
+ if ( recoveredAddr === un . address . toLowerCase ( ) ) {
88
+ return true
89
+ }
90
+ } else {
91
+ throw new Error ( `Blockchain "${ un . blockchain } " not supported` )
92
+ }
93
+ // we should not be here
94
+ return false
30
95
}
31
96
32
97
public static async validateChallenge ( endPoint : string , data : UNInterface ) {
0 commit comments