-
Notifications
You must be signed in to change notification settings - Fork 7
/
intent_typed.go
120 lines (108 loc) · 2.74 KB
/
intent_typed.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
package intents
import (
"encoding/json"
"fmt"
"time"
)
func IntentDataTypeToName[T any](t *T) IntentName {
var data any = t
switch data.(type) {
case *IntentDataOpenSession:
return IntentName_openSession
case *IntentDataCloseSession:
return IntentName_closeSession
case *IntentDataValidateSession:
return IntentName_validateSession
case *IntentDataFinishValidateSession:
return IntentName_finishValidateSession
case *IntentDataListSessions:
return IntentName_listSessions
case *IntentDataGetSession:
return IntentName_getSession
case *IntentDataSessionAuthProof:
return IntentName_sessionAuthProof
case *IntentDataSignMessage:
return IntentName_signMessage
case *IntentDataFeeOptions:
return IntentName_feeOptions
case *IntentDataSendTransaction:
return IntentName_sendTransaction
case *IntentDataGetTransactionReceipt:
return IntentName_getTransactionReceipt
case *IntentDataListAccounts:
return IntentName_listAccounts
case *IntentDataFederateAccount:
return IntentName_federateAccount
case *IntentDataRemoveAccount:
return IntentName_removeAccount
default:
return ""
}
}
type IntentTyped[T any] struct {
Intent
Data T `json:"data"`
}
func NewIntentTyped[T any](data T) *IntentTyped[T] {
return &IntentTyped[T]{
Intent: Intent{
Version: "1",
ExpiresAt: uint64(time.Now().Unix()) + IntentValidTimeInSec,
IssuedAt: uint64(time.Now().Unix()),
Name: IntentDataTypeToName(&data),
Data: data,
},
Data: data,
}
}
func NewIntentTypedFromIntent[T any](intent *Intent) (*IntentTyped[T], error) {
switch intent.Data.(type) {
case T:
return &IntentTyped[T]{
Intent: *intent,
Data: intent.Data.(T),
}, nil
case map[string]any:
data := intent.Data.(map[string]any)
// convert to json
dataJSON, err := json.Marshal(data)
if err != nil {
return nil, err
}
// convert to typed data
var typedData T
err = json.Unmarshal(dataJSON, &typedData)
if err != nil {
return nil, err
}
// check if intent name and data type match
if IntentDataTypeToName(&typedData) != intent.Name {
return nil, fmt.Errorf("intent name and data type mismatch")
}
return &IntentTyped[T]{
Intent: *intent,
Data: typedData,
}, nil
default:
return nil, fmt.Errorf("invalid intent data type")
}
}
func (i *IntentTyped[T]) IsValid() error {
// check if the intent is valid
if err := i.Intent.IsValid(); err != nil {
return err
}
// check if the intent data is valid
var data any = &i.Data
if validator, ok := data.(IntentDataValidator); ok {
if err := validator.IsValid(); err != nil {
return fmt.Errorf("invalid intent data: %w", err)
}
}
// the intent is valid
return nil
}
func (i *IntentTyped[T]) ToIntent() *Intent {
i.Intent.Data = i.Data
return &i.Intent
}