Skip to content

Commit 08c6583

Browse files
author
Conor Okus
committed
Updated tutorials for LDK 0.0.116
1 parent e3ba71e commit 08c6583

File tree

4 files changed

+140
-54
lines changed

4 files changed

+140
-54
lines changed

docs/tutorials/building-a-node-with-ldk/closing-a-channel.md

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ let channelId: [UInt8] = // Add Channel Id in bytes
2424
let counterpartyNodeId: [UInt8] = // Add Counterparty Node Id in bytes
2525
let res = channelManager.closeChannel(channelId: channelId, counterpartyNodeId: counterpartyNodeId)
2626
if res!.isOk() {
27-
print("Channel Closed")
27+
// Channel Closed
2828
}
2929
```
3030

@@ -52,19 +52,21 @@ Claim Funds using Custom KeysManager. (Single Fees)
5252
<template v-slot:swift>
5353

5454
```Swift
55+
// Custom KeysManager to get funds directly back to the BDK wallet after Channel Close
5556
class MyKeysManager {
5657
let keysManager: KeysManager
57-
let signerProvider: MySignerProvider // Use signerProvider instead of asSignerProvider()
58-
let wallet: Wallet
59-
60-
init(seed: [UInt8], startingTimeSecs: UInt64, startingTimeNanos: UInt32, wallet: Wallet) {
58+
let signerProvider: MySignerProvider
59+
let wallet: BitcoinDevKit.Wallet
60+
61+
init(seed: [UInt8], startingTimeSecs: UInt64, startingTimeNanos: UInt32, wallet: BitcoinDevKit.Wallet) {
6162
self.keysManager = KeysManager(seed: seed, startingTimeSecs: startingTimeSecs, startingTimeNanos: startingTimeNanos)
6263
self.wallet = wallet
6364
signerProvider = MySignerProvider()
6465
signerProvider.myKeysManager = self
6566
}
6667
}
6768

69+
// Custom SignerProvider to override getDestinationScript() and getShutdownScriptpubkey()
6870
class MySignerProvider: SignerProvider {
6971
weak var myKeysManager: MyKeysManager?
7072
override func deriveChannelSigner(channelValueSatoshis: UInt64, channelKeysId: [UInt8]) -> Bindings.WriteableEcdsaChannelSigner {
@@ -79,16 +81,16 @@ class MySignerProvider: SignerProvider {
7981
return myKeysManager!.keysManager.asSignerProvider().readChanSigner(reader: reader)
8082
}
8183

82-
override func getDestinationScript() -> [UInt8] {
84+
override func getDestinationScript() -> Bindings.Result_ScriptNoneZ {
8385
do {
8486
let address = try myKeysManager!.wallet.getAddress(addressIndex: .new)
85-
return address.address.scriptPubkey().toBytes()
87+
return Bindings.Result_ScriptNoneZ.initWithOk(o: address.address.scriptPubkey().toBytes())
8688
} catch {
8789
return myKeysManager!.keysManager.asSignerProvider().getDestinationScript()
8890
}
8991
}
90-
91-
override func getShutdownScriptpubkey() -> Bindings.ShutdownScript {
92+
93+
override func getShutdownScriptpubkey() -> Bindings.Result_ShutdownScriptNoneZ {
9294
do {
9395
let address = try myKeysManager!.wallet.getAddress(addressIndex: .new).address
9496
let payload = address.payload()
@@ -132,7 +134,7 @@ class MySignerProvider: SignerProvider {
132134
}
133135
let res = ShutdownScript.newWitnessProgram(version: ver, program: program)
134136
if res.isOk() {
135-
return res.getValue()!
137+
return Bindings.Result_ShutdownScriptNoneZ.initWithOk(o: res.getValue()!)
136138
}
137139
}
138140
return myKeysManager!.keysManager.asSignerProvider().getShutdownScriptpubkey()
@@ -141,6 +143,7 @@ class MySignerProvider: SignerProvider {
141143
}
142144
}
143145
}
146+
144147
```
145148

146149
</template>
@@ -170,14 +173,22 @@ func handleEvent(event: Event) {
170173
if let event = event.getValueAsSpendableOutputs() {
171174
let outputs = event.getOutputs()
172175
do {
173-
let address = ldkManager!.bdkManager.getAddress(addressIndex: .new)!
176+
let address = // Get an address to transfer the funds
174177
let script = try Address(address: address).scriptPubkey().toBytes()
175-
let res = ldkManager?.keysManager?.spendSpendableOutputs(descriptors: outputs, outputs: [], changeDestinationScript: script, feerateSatPer1000Weight: 1000)
176-
if res!.isOk() {
177-
ldkManager.broadcaster.broadcastTransaction(tx: res!.getValue()!)
178+
let res = ldkManager.keysManager.spendSpendableOutputs(
179+
descriptors: outputs,
180+
outputs: [],
181+
changeDestinationScript: script,
182+
feerateSatPer1000Weight: 1000,
183+
locktime: nil
184+
)
185+
if res.isOk() {
186+
var txs: [[UInt8]] = []
187+
txs.append(res.getValue()!)
188+
ldkManager.broadcaster.broadcastTransactions(txs: txs)
178189
}
179190
} catch {
180-
print(error)
191+
print(error.localizedDescription)
181192
}
182193
}
183194
}

docs/tutorials/building-a-node-with-ldk/opening-a-channel.md

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,9 @@ userConfig.setChannelHandshakeConfig(val: channelConfig)
6868

6969
let createChannelResults = channelManager.createChannel(
7070
theirNetworkKey: pubKey,
71-
channelValueSatoshis: amount,
72-
pushMsat: pushMsat,
73-
userChannelId: userId,
71+
channelValueSatoshis: amount,
72+
pushMsat: pushMsat,
73+
userChannelId: userId,
7474
overrideConfig: userConfig
7575
)
7676
```
@@ -81,7 +81,7 @@ let createChannelResults = channelManager.createChannel(
8181

8282
# FundingGenerationReady Event Handling
8383

84-
At this point, an outbound channel has been initiated with your peer and it will appear in `ChannelManager::list_channels`. However, the channel is not yet funded. Once your peer accepts the channel, you will be notified with a `FundingGenerationReady` event. It's then your responsibility to construct the funding transaction and pass it to ChannelManager, which will broadcast it once it receives your channel counterparty's signature.
84+
At this point, an outbound channel has been initiated with your peer and it will appear in `ChannelManager::list_channels`. However, the channel is not yet funded. Once your peer accepts the channel, you will be notified with a `FundingGenerationReady` event. It's then your responsibility to construct the funding transaction and pass it to ChannelManager, which will broadcast it once it receives your channel counterparty's signature.
8585

8686
::: tip Note
8787

@@ -180,8 +180,8 @@ if let event = event.getValueAsFundingGenerationReady() {
180180
let rawTx = buildFundingTx(script: script, amount: channelValue)
181181
if let rawTx = rawTx {
182182
channelManager.fundingTransactionGenerated(
183-
temporaryChannelId: event.getTemporaryChannelId(),
184-
counterpartyNodeId: event.getCounterpartyNodeId(),
183+
temporaryChannelId: event.getTemporaryChannelId(),
184+
counterpartyNodeId: event.getCounterpartyNodeId(),
185185
fundingTransaction: rawTx.serialize()
186186
)
187187
}
@@ -208,7 +208,6 @@ func buildFundingTx(script: Script, amount: UInt64) -> Transaction? {
208208
</CodeSwitcher>
209209

210210
**References:** [Rust `FundingGenerationReady` docs](https://docs.rs/lightning/*/lightning/util/events/enum.Event.html#variant.FundingGenerationReady), [Java `FundingGenerationReady` bindings](https://github.com/lightningdevkit/ldk-garbagecollected/blob/main/src/main/java/org/ldk/structs/Event.java#L95)
211-
212211
# Broadcasting the Funding Transaction
213212

214213
After crafting the funding transaction you'll need to send it to the Bitcoin network where it will hopefully be mined and added to the blockchain. You'll need to watch this transaction and wait for a minimum of 6 confirmations before the channel is ready to use.
@@ -261,8 +260,8 @@ object YourTxBroadcaster : BroadcasterInterface.BroadcasterInterfaceInterface {
261260
val transaction = Transaction(uByteArray.toList())
262261

263262
tx?.let {
264-
CoroutineScope(Dispatchers.IO).launch {
265-
blockchain.broadcast(transaction)
263+
CoroutineScope(Dispatchers.IO).launch {
264+
blockchain.broadcast(transaction)
266265
}
267266
} ?: throw(IllegalStateException("Broadcaster attempted to broadcast a null transaction"))
268267

@@ -277,19 +276,22 @@ object YourTxBroadcaster : BroadcasterInterface.BroadcasterInterfaceInterface {
277276

278277
```Swift
279278
// Using BDK (Bitcoin Dev Kit) to broadcast a transaction via the esplora client
279+
import BitcoinDevKit
280+
280281
class MyBroacaster: BroadcasterInterface {
281-
override func broadcastTransaction(tx: [UInt8]) {
282+
override func broadcastTransactions(txs: [[UInt8]]) {
282283
let esploraURL = "esploraUrl"
283-
let esploraConfig = EsploraConfig(baseUrl: esploraURL, proxy: nil, concurrency: 5, stopGap: 20, timeout: nil)
284+
let esploraConfig = EsploraConfig(baseUrl: esploraURL, proxy: nil, concurrency: 5, stopGap: 20, timeout: nil)
284285
let blockchainConfig = BlockchainConfig.esplora(config: esploraConfig)
285-
let blockchain = Blockchain(config: blockchainConfig)
286-
287-
do {
288-
let transaction = try Transaction(transactionBytes: tx)
289-
try blockchain.broadcast(transaction: transaction)
290-
} catch {
291-
print("Failed to broadcast transaction: \(error.localizedDescription)")
292-
}
286+
do {
287+
let blockchain = try Blockchain(config: blockchainConfig)
288+
for tx in txs {
289+
let transaction = try Transaction(transactionBytes: tx)
290+
try blockchain.broadcast(transaction: transaction)
291+
}
292+
} catch {
293+
print("Failed to broadcast transaction: \(error.localizedDescription)")
294+
}
293295
}
294296
}
295297
```

docs/tutorials/building-a-node-with-ldk/sending-payments.md

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -130,22 +130,22 @@ if (parsed_invoice instanceof Result_InvoiceNoneZ.Result_InvoiceNoneZ_OK) {
130130

131131
<template v-slot:swift>
132132

133-
```Swift
134-
let invoiceStr = // get an invoice from the payee
135-
let parsedInvoice = Invoice.fromStr(s: invoiceStr)
136-
137-
if parsedInvoice.getValue() != nil {
138-
let invoicePaymentResult = Bindings.payInvoice(
139-
invoice: invoice,
140-
retryStrategy: Bindings.Retry.initWithTimeout(a: 15),
141-
channelmanager: channelManager
142-
)
143-
144-
if invoicePaymentResult.isOk() {
145-
// Payment Sent
133+
```Swift
134+
let invoiceStr = // get an invoice from the payee
135+
let parsedInvoice = Bolt11Invoice.fromStr(s: invoiceStr)
136+
137+
if let invoiceVal = parsedInvoice.getValue() {
138+
let invoicePaymentResult = Bindings.payInvoice(
139+
invoice: invoiceVal,
140+
retryStrategy: Bindings.Retry.initWithTimeout(a: 15),
141+
channelmanager: channelManager
142+
)
143+
144+
if invoicePaymentResult.isOk() {
145+
// Payment Sent
146+
}
146147
}
147-
}
148-
```
148+
```
149149

150150
</template>
151151

@@ -202,4 +202,4 @@ if let paymentSentEvent = event.getValueAsPaymentSent() {
202202

203203
</template>
204204

205-
</CodeSwitcher>
205+
</CodeSwitcher>

docs/tutorials/building-a-node-with-ldk/setting-up-a-channel-manager.md

Lines changed: 77 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,7 @@ retrieving fresh ones every time
266266

267267
```Swift
268268
class MyBroacaster: BroadcasterInterface {
269-
override func broadcastTransaction(tx: [UInt8]) {
269+
override func broadcastTransactions(txs: [[UInt8]]) {
270270
// Insert code to broadcast the given transaction
271271
}
272272
}
@@ -1036,9 +1036,10 @@ if readResult.isOk() {
10361036
}
10371037

10381038
// If Network Graph does not exist, create a new one
1039-
netGraph = NetworkGraph(network: network, logger: logger)
1039+
let netGraph = NetworkGraph(network: network, logger: logger)
10401040

1041-
let rgs = RapidGossipSync(networkGraph: netGraph, logger: logger) // Initialise RGS
1041+
// Initialise RGS
1042+
let rgs = RapidGossipSync(networkGraph: netGraph, logger: logger)
10421043
if let lastSync = netGraph.getLastRapidGossipSyncTimestamp(), let snapshot = getSnapshot(lastSyncTimeStamp: lastSync) {
10431044
let timestampSeconds = UInt64(NSDate().timeIntervalSince1970)
10441045
let res = rgs.updateNetworkGraphNoStd(updateData: snapshot, currentTimeUnix: timestampSeconds)
@@ -1055,7 +1056,8 @@ if let lastSync = netGraph.getLastRapidGossipSyncTimestamp(), let snapshot = get
10551056

10561057
// Get current snapshot from the RGS Server
10571058
func getSnapshot(lastSyncTimeStamp: UInt32) -> [UInt8]? {
1058-
let url: URL = URL(string: "https://rapidsync.lightningdevkit.org/snapshot/\(lastSyncTimeStamp)")! // Use LDK's RGS Server or use your own Server
1059+
// Use LDK's RGS Server or use your own Server
1060+
let url: URL = URL(string: "https://rapidsync.lightningdevkit.org/snapshot/\(lastSyncTimeStamp)")!
10591061
let data = // Use the url to get the data
10601062
if let data = data {
10611063
return [UInt8](data)
@@ -1077,3 +1079,74 @@ func getSnapshot(lastSyncTimeStamp: UInt32) -> [UInt8]? {
10771079
**Optional dependency:** `Access`, a source of chain information. Recommended to be able to verify channels before adding them to the internal network graph.
10781080

10791081
**References:** [Rust `P2PGossipSync` docs](https://docs.rs/lightning/*/lightning/routing/gossip/struct.P2PGossipSync.html), [`Access` docs](https://docs.rs/lightning/*/lightning/chain/trait.Access.html), [Java `P2PGossipSync` bindings](https://github.com/lightningdevkit/ldk-garbagecollected/blob/main/src/main/java/org/ldk/structs/P2PGossipSync.java), [Rust `RapidGossipSync` docs](https://docs.rs/lightning-rapid-gossip-sync/*/lightning_rapid_gossip_sync/), [Java `RapidGossipSync` bindings](https://github.com/lightningdevkit/ldk-garbagecollected/blob/main/src/main/java/org/ldk/structs/RapidGossipSync.java)
1082+
1083+
### Optional: Initialize `Probabilistic Scorer`
1084+
1085+
**You must follow this step if:** TODO
1086+
1087+
**What it's used for:** TODO
1088+
1089+
<CodeSwitcher :languages="{rust:'Rust', kotlin:'Kotlin', swift:'Swift'}">
1090+
1091+
<template v-slot:rust>
1092+
1093+
```rust
1094+
// TODO: Add Rust Code Here
1095+
```
1096+
1097+
</template>
1098+
1099+
<template v-slot:kotlin>
1100+
1101+
```java
1102+
// TODO: Add Java Code Here
1103+
```
1104+
1105+
</template>
1106+
1107+
<template v-slot:swift>
1108+
1109+
```Swift
1110+
// If Scorer exists, then read from disk
1111+
let serializedScorer = // Read Scorer bytes from file
1112+
let decayParams = ProbabilisticScoringDecayParameters.initWithDefault()
1113+
let serializedProbabilisticScorer = ProbabilisticScorer.read(
1114+
ser: serializedScorer,
1115+
argA: decayParams,
1116+
argB: netGraph,
1117+
argC: logger
1118+
)
1119+
if let res = serializedProbabilisticScorer.getValue() {
1120+
let probabilisticScorer = res
1121+
let score = probabilisticScorer.asScore()
1122+
1123+
// Scorer loaded
1124+
let scorer = MultiThreadedLockableScore(score: score)
1125+
}
1126+
1127+
// If Scorer does not exist, create a new one
1128+
let decayParams = ProbabilisticScoringDecayParameters.initWithDefault()
1129+
let probabilisticScorer = ProbabilisticScorer(
1130+
decayParams: decayParams,
1131+
networkGraph: netGraph,
1132+
logger: logger
1133+
)
1134+
let score = probabilisticScorer.asScore()
1135+
1136+
// Scorer loaded
1137+
let scorer = MultiThreadedLockableScore(score: score)
1138+
```
1139+
1140+
</template>
1141+
1142+
1143+
</CodeSwitcher>
1144+
1145+
1146+
**Implementation notes:** TODO
1147+
1148+
**Dependencies:** TODO
1149+
1150+
**Optional dependency:** TODO
1151+
1152+
**References:** TODO

0 commit comments

Comments
 (0)