forked from stellar/go
-
Notifications
You must be signed in to change notification settings - Fork 0
/
transaction_challenge_example_test.go
136 lines (125 loc) · 4.43 KB
/
transaction_challenge_example_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
package txnbuild_test
import (
"fmt"
"sort"
"time"
"github.com/stellar/go/clients/horizonclient"
"github.com/stellar/go/keypair"
"github.com/stellar/go/network"
"github.com/stellar/go/protocols/horizon"
"github.com/stellar/go/txnbuild"
)
var serverAccount, _ = keypair.ParseFull("SCDXPYDGKV5HOAGVZN3FQSS5FKUPP5BAVBWH4FXKTAWAC24AE4757JSI")
var clientAccount, _ = keypair.ParseFull("SANVNCABRBVISCV7KH4SZVBKPJWWTT4424OVWUHUHPH2MVSF6RC7HPGN")
var clientSigner1, _ = keypair.ParseFull("SBPQUZ6G4FZNWFHKUWC5BEYWF6R52E3SEP7R3GWYSM2XTKGF5LNTWW4R")
var clientSigner2, _ = keypair.ParseFull("SBMSVD4KKELKGZXHBUQTIROWUAPQASDX7KEJITARP4VMZ6KLUHOGPTYW")
var horizonClient = func() horizonclient.ClientInterface {
client := &horizonclient.MockClient{}
client.
On("AccountDetail", horizonclient.AccountRequest{AccountID: clientAccount.Address()}).
Return(
horizon.Account{
Thresholds: horizon.AccountThresholds{LowThreshold: 1, MedThreshold: 10, HighThreshold: 100},
Signers: []horizon.Signer{
{Key: clientSigner1.Address(), Weight: 40},
{Key: clientSigner2.Address(), Weight: 60},
},
},
nil,
)
return client
}()
func ExampleVerifyChallengeTxThreshold() {
// Server builds challenge transaction
var challengeTx string
{
tx, err := txnbuild.BuildChallengeTx(serverAccount.Seed(), clientAccount.Address(), "webauthdomain.stellar.org", "test", network.TestNetworkPassphrase, time.Minute, nil)
if err != nil {
fmt.Println("Error:", err)
return
}
challengeTx, err = tx.Base64()
if err != nil {
fmt.Println("Error:", err)
return
}
}
// Client reads and signs challenge transaction
var signedChallengeTx string
{
tx, txClientAccountID, _, _, err := txnbuild.ReadChallengeTx(challengeTx, serverAccount.Address(), network.TestNetworkPassphrase, "webauthdomain.stellar.org", []string{"test"})
if err != nil {
fmt.Println("Error:", err)
return
}
if txClientAccountID != clientAccount.Address() {
fmt.Println("Error: challenge tx is not for expected client account")
return
}
tx, err = tx.Sign(network.TestNetworkPassphrase, clientSigner1, clientSigner2)
if err != nil {
fmt.Println("Error:", err)
return
}
signedChallengeTx, err = tx.Base64()
if err != nil {
fmt.Println("Error:", err)
return
}
}
// Server verifies signed challenge transaction
{
_, txClientAccountID, _, memo, err := txnbuild.ReadChallengeTx(challengeTx, serverAccount.Address(), network.TestNetworkPassphrase, "webauthdomain.stellar.org", []string{"test"})
if err != nil {
fmt.Println("Error:", err)
return
} else if memo != nil {
fmt.Println("Expected memo to be nil, got: ", memo)
return
}
// Server gets account
clientAccountExists := false
horizonClientAccount, err := horizonClient.AccountDetail(horizonclient.AccountRequest{AccountID: txClientAccountID})
if horizonclient.IsNotFoundError(err) {
clientAccountExists = false
fmt.Println("Account does not exist, use master key to verify")
} else if err == nil {
clientAccountExists = true
} else {
fmt.Println("Error:", err)
return
}
if clientAccountExists {
// Server gets list of signers from account
signerSummary := horizonClientAccount.SignerSummary()
// Server chooses the threshold to require: low, med or high
threshold := txnbuild.Threshold(horizonClientAccount.Thresholds.MedThreshold)
// Server verifies threshold is met
signers, err := txnbuild.VerifyChallengeTxThreshold(signedChallengeTx, serverAccount.Address(), network.TestNetworkPassphrase, "webauthdomain.stellar.org", []string{"test"}, threshold, signerSummary)
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Println("Client Signers Verified:")
sort.Strings(signers)
for _, signer := range signers {
fmt.Println(signer, "weight:", signerSummary[signer])
}
} else {
// Server verifies that master key has signed challenge transaction
signersFound, err := txnbuild.VerifyChallengeTxSigners(signedChallengeTx, serverAccount.Address(), network.TestNetworkPassphrase, "webauthdomain.stellar.org", []string{"test"}, txClientAccountID)
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Println("Client Master Key Verified:")
for _, signerFound := range signersFound {
fmt.Println(signerFound)
}
}
}
// Output:
// Client Signers Verified:
// GAS4V4O2B7DW5T7IQRPEEVCRXMDZESKISR7DVIGKZQYYV3OSQ5SH5LVP weight: 60
// GDQNY3PBOJOKYZSRMK2S7LHHGWZIUISD4QORETLMXEWXBI7KFZZMKTL3 weight: 40
}