Skip to content

Commit 86236bd

Browse files
committed
begin migration of Java Sample Node documentation for Swift
1 parent 5da127e commit 86236bd

File tree

1 file changed

+204
-0
lines changed

1 file changed

+204
-0
lines changed

docs/setup.md

+204
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,204 @@
1+
# Setup
2+
3+
This project is essentially a set of auto-generated decorators that call the C methods
4+
defined in lightning.h. The wrappers for the most part take care of conveniences such
5+
as conversion of Swift types into C types, and parsing C types back into Swift.
6+
7+
In Bindings.swift, there are various additional generic utility methods to aid the
8+
developer in passing data back and forth.
9+
10+
The greatest effort on the part of users of this project comes in when dealing with
11+
traits. All files located within `bindings/LDK/traits` are meant to be interpreted as
12+
abstract classes. However, as Swift does not allow abstract classes, and using protocols
13+
would shift both implementation and boilerplate burden on developers, I instead recommend
14+
an override pattern, which I will describe in the next step.
15+
16+
This guide is essentially a conversion of the [Java guide](https://lightningdevkit.org/docs/build_node)
17+
for Swift.
18+
19+
## Phase 1: Trait Overrides
20+
21+
The first set of steps we need to set up is create classes to override the trait classes.
22+
In these example, we will simply be taking trait names such as `FeeEstimator` and
23+
create classes inheriting from them prefixed with `My-`.
24+
25+
### FeeEstimator
26+
27+
First, define an inheriting class called `MyFeeEstimator`:
28+
29+
```swift
30+
// MyFeeEstimator.swift
31+
32+
import Foundation
33+
34+
class MyFeeEstimator: FeeEstimator {
35+
36+
override func get_est_sat_per_1000_weight(confirmation_target: LDKConfirmationTarget) -> UInt32 {
37+
return 253
38+
}
39+
40+
}
41+
```
42+
43+
Second, somewhere within the app initialization context, e.g. the app delegate's
44+
`didFinishLaunchingWithOptions` method, instantiate the fee estimator:
45+
46+
```swift
47+
// main context
48+
49+
let feeEstimator = MyFeeEstimator()
50+
```
51+
52+
### Logger
53+
54+
Define the inheriting class:
55+
56+
```swift
57+
// MyLogger.swift
58+
59+
import Foundation
60+
61+
class MyLogger: Logger {
62+
63+
override func log(record: UnsafePointer<Int8>?) {
64+
if let record = record {
65+
let string = Bindings.UnsafeIntPointer_to_string(nativeType: record)
66+
print("record: \(string)")
67+
}
68+
}
69+
70+
}
71+
```
72+
73+
Instantiate the value:
74+
75+
```swift
76+
// main context (continued)
77+
78+
let logger = MyLogger()
79+
```
80+
81+
### BroadcasterInterface
82+
83+
Define the subclass:
84+
85+
```swift
86+
// MyBroadcasterInterface.swift
87+
88+
import Foundation
89+
90+
class MyBroadcasterInterface: BroadcasterInterface {
91+
92+
override func broadcast_transaction(tx: LDKTransaction) {
93+
let txBytes: [UInt8] = Bindings.LDKTransaction_to_array(nativeType: tx)
94+
// insert code to broadcast transaction
95+
}
96+
97+
}
98+
```
99+
100+
Instantiate it:
101+
102+
```swift
103+
// main context (continued)
104+
105+
let broadcaster = MyBroadcasterInterface()
106+
```
107+
108+
### Persist
109+
110+
Define the subclass:
111+
112+
```swift
113+
// MyPersister.swift
114+
115+
import Foundation
116+
117+
class MyPersister: Persist {
118+
119+
override func persist_new_channel(id: LDKOutPoint, data: UnsafePointer<LDKChannelMonitor>) -> Result_NoneChannelMonitorUpdateErrZ {
120+
let outPoint = OutPoint(pointer: id)
121+
let idBytes: [UInt8] = outPoint.write(obj: outPoint)
122+
123+
let channelMonitor = ChannelMonitor(pointer: data.pointee)
124+
let monitorBytes: [UInt8] = channelMonitor.write(obj: channelMonitor)
125+
126+
// persist monitorBytes to disk, keyed by idBytes
127+
128+
return Result_NoneChannelMonitorUpdateErrZ(pointer: LDKCResult_NoneChannelMonitorUpdateErrZ())
129+
}
130+
131+
override func update_persisted_channel(id: LDKOutPoint, update: UnsafePointer<LDKChannelMonitorUpdate>, data: UnsafePointer<LDKChannelMonitor>) -> Result_NoneChannelMonitorUpdateErrZ {
132+
let outPoint = OutPoint(pointer: id)
133+
let idBytes: [UInt8] = outPoint.write(obj: outPoint)
134+
135+
let channelMonitor = ChannelMonitor(pointer: data.pointee)
136+
let monitorBytes: [UInt8] = channelMonitor.write(obj: channelMonitor)
137+
138+
// modify persisted monitorBytes keyed by idBytes on disk
139+
140+
return Result_NoneChannelMonitorUpdateErrZ(pointer: LDKCResult_NoneChannelMonitorUpdateErrZ())
141+
}
142+
143+
}
144+
```
145+
146+
Instantiate it:
147+
148+
```swift
149+
// main context (continued)
150+
151+
let persister = MyPersister()
152+
```
153+
154+
### Filter
155+
156+
Define the subclass:
157+
158+
```swift
159+
// MyFilter.swift
160+
161+
import Foundation
162+
163+
class MyFilter: Filter {
164+
override func register_tx(txid: UnsafePointer<(UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8)>?, script_pubkey: LDKu8slice) {
165+
let txidBytes = Bindings.tuple32_to_array(nativeType: txid!.pointee)
166+
let scriptPubkeyBytes = Bindings.LDKu8slice_to_array(nativeType: script_pubkey)
167+
168+
// watch this transaction on-chain
169+
}
170+
171+
override func register_output(output: LDKWatchedOutput) -> Option_C2Tuple_usizeTransactionZZ {
172+
let watchedOutput = WatchedOutput(pointer: output)
173+
let scriptPubkeyBytes = watchedOutput.get_script_pubkey()
174+
let outpoint = watchedOutput.get_outpoint()
175+
let txidBytes = Bindings.tuple32_to_array(nativeType: outpoint.get_txid())
176+
let outputIndex = outpoint.get_index()
177+
178+
// watch for any transactions that spend this output on-chain
179+
180+
let blockHashBytes = watchedOutput.get_block_hash()
181+
// TODO: if block hash bytes are not null, return any transaction spending the output that is found in the corresponding block along with its index
182+
183+
return Option_C2Tuple_usizeTransactionZZ(pointer: LDKCOption_C2Tuple_usizeTransactionZZ())
184+
}
185+
}
186+
```
187+
188+
Instantiate it:
189+
190+
```swift
191+
// main context (continued)
192+
193+
let filter = MyFilter()
194+
```
195+
196+
## Phase 2: Initializations
197+
198+
### ChainMonitor
199+
200+
```swift
201+
// main context (continued)
202+
203+
let chainMonitor = ChainMonitor.init(chain_source: filter, broadcaster: broadcaster, logger: logger, feeest: feeEstimator, persister: persister)
204+
```

0 commit comments

Comments
 (0)