-
Notifications
You must be signed in to change notification settings - Fork 127
Expand file tree
/
Copy pathdeposit.go
More file actions
248 lines (190 loc) · 6.28 KB
/
deposit.go
File metadata and controls
248 lines (190 loc) · 6.28 KB
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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
package deposit
import (
"context"
"encoding/hex"
"fmt"
"time"
"github.com/btcsuite/btcd/btcec/v2"
"github.com/btcsuite/btcd/wire"
"github.com/btcsuite/btcwallet/wtxmgr"
"github.com/lightninglabs/loop/assets"
"github.com/lightninglabs/taproot-assets/proof"
)
// State is the enum used for deposit states.
type State uint8
const (
// StateInitiated indicates that the deposit has been initiated by the
// client.
StateInitiated State = 0
// StatePending indicates that the deposit is pending confirmation on
// the blockchain.
StatePending State = 1
// StateConfirmed indicates that the deposit has been confirmed on the
// blockchain.
StateConfirmed State = 2
// StateExpired indicates that the deposit has expired.
StateExpired State = 3
// StateTimeoutSweepPublished indicates that the timeout sweep has been
// published.
StateTimeoutSweepPublished State = 4
// StateWithdrawn indicates that the deposit has been withdrawn.
StateWithdrawn State = 5
// StateCooperativeSweepPublished indicates that the cooperative sweep
// withdrawing the deposit has been published.
StateCooperativeSweepPublished State = 6
// StateKeyRevealed indicates that the client has revealed a valid key
// for the deposit which is now ready to be swept.
StateKeyRevealed State = 7
// StateSpent indicates that the deposit has been spent.
StateSpent State = 8
// StateSwept indicates that the deposit has been swept, either by a
// timeout sweep or a cooperative (ie withdrawal) sweep.
StateSwept State = 9
)
// String coverts a deposit state to human readable string.
func (s State) String() string {
switch s {
case StateInitiated:
return "Initiated"
case StatePending:
return "Pending"
case StateConfirmed:
return "Confirmed"
case StateExpired:
return "Expired"
case StateTimeoutSweepPublished:
return "TimeoutSweepPublished"
case StateWithdrawn:
return "Withdrawn"
case StateCooperativeSweepPublished:
return "CooperativeSweepPublished"
case StateKeyRevealed:
return "KeyRevealed"
case StateSpent:
return "Spent"
case StateSwept:
return "Swept"
default:
return "Unknown"
}
}
// IsFinal returns true if the deposit state is final, meaning that no further
// actions can be taken on the deposit.
func (s State) IsFinal() bool {
return s == StateSpent || s == StateSwept
}
// Info holds publicly available information about an asset deposit.
// It is used to communicate deposit details to clients of the deposit Manager.
type Info struct {
// ID is the unique identifier for this deposit which will also be used
// to store the deposit in both the server and client databases.
ID string
// Version is the protocol version of the deposit.
Version AssetDepositProtocolVersion
// CreatedAt is the time when the deposit was created (on the client).
CreatedAt time.Time
// Amount is the amount of asset to be deposited.
Amount uint64
// Addr is the TAP deposit address where the asset will be sent.
Addr string
// State is the deposit state.
State State
// ConfirmationHeight is the block height at which the deposit was
// confirmed.
ConfirmationHeight uint32
// Outpoint is the anchor outpoint of the deposit. It is only set if the
// deposit has been confirmed.
Outpoint *wire.OutPoint
// Expiry is the block height at which the deposit will expire. It is
// only set if the deposit has been confirmed.
Expiry uint32
// SweepScriptKey is the script key of the swept asset.
SweepScriptKey *btcec.PublicKey
// SweepInternalKey is the internal key of output of the swept asset.
SweepInternalKey *btcec.PublicKey
}
// Copy creates a copy of the Info struct.
func (d *Info) Copy() *Info {
info := &Info{
ID: d.ID,
Version: d.Version,
CreatedAt: d.CreatedAt,
Amount: d.Amount,
Addr: d.Addr,
State: d.State,
ConfirmationHeight: d.ConfirmationHeight,
Expiry: d.Expiry,
}
if d.Outpoint != nil {
info.Outpoint = &wire.OutPoint{
Hash: d.Outpoint.Hash,
Index: d.Outpoint.Index,
}
}
if d.SweepScriptKey != nil {
pubKey := *d.SweepScriptKey
info.SweepScriptKey = &pubKey
}
if d.SweepInternalKey != nil {
pubKey := *d.SweepInternalKey
info.SweepInternalKey = &pubKey
}
return info
}
// Deposit is the struct that holds all the information about an asset deposit.
type Deposit struct {
*Kit
*Info
// PkScript is the pkscript of the deposit anchor output.
PkScript []byte
// Proof is the proof of the deposit transfer.
Proof *proof.Proof
// AnchorRootHash is the root hash of the deposit anchor output.
AnchorRootHash []byte
}
// fundingLabel returns a string label that we can use for marking a transfer
// funding the deposit. This is useful if we need to filter deposits.
func (d *Deposit) fundingLabel() string {
return fmt.Sprintf("deposit funding %v", d.ID)
}
// timeoutSweepLabel is a string label that we can use for marking a timeout
// sweep transfer. This is useful if we need to filter deposits.
func (d *Deposit) timeoutSweepLabel() string {
return fmt.Sprintf("deposit timeout sweep %v", d.ID)
}
// withdrawLabel is a string label that we can use for marking a withdrawal
// sweep transfer. This is useful if we need to filter deposits.
func (d *Deposit) withdrawLabel() string {
return fmt.Sprintf("deposit withdraw sweep %v", d.ID)
}
// lockID converts a deposit ID to a lock ID. The lock ID is used to lock inputs
// used for the deposit sweep transaction. Note that we assume that the deposit
// ID is a hex-encoded string of the same length as the lock ID.
func (d *Deposit) lockID() (wtxmgr.LockID, error) {
var lockID wtxmgr.LockID
depositIDBytes, err := hex.DecodeString(d.ID)
if err != nil {
return wtxmgr.LockID{}, err
}
if len(depositIDBytes) != len(lockID) {
return wtxmgr.LockID{}, fmt.Errorf("invalid deposit ID "+
"length: %d", len(depositIDBytes))
}
copy(lockID[:], depositIDBytes)
return lockID, nil
}
// GenerateSweepKeys generates the sweep script key and internal key for the
// deposit sweep.
func (d *Deposit) GenerateSweepKeys(ctx context.Context,
client *assets.TapdClient) error {
if d.SweepScriptKey != nil {
return nil
}
scriptKey, internalKeyDesc, err := client.DeriveNewKeys(ctx)
if err != nil {
return err
}
d.SweepScriptKey = scriptKey.PubKey
d.SweepInternalKey = internalKeyDesc.PubKey
return nil
}