Created
June 3, 2023 00:11
-
-
Save valldrac/54ff6842e4cc6d624ab893f4e839b2ae to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
suspend fun restoreAndRefreshExample(context: Context) = coroutineScope { | |
// Connect to the SDK wallet service. | |
val provider = WalletProvider.connect(context) | |
// Define 2 onion nodes. | |
val torNodes = listOf( | |
"http://3g2upl4pq6kufc4m.onion:18082", | |
"http://33y6fjyhs3phzfjj.onion:18082", | |
).map { url -> RemoteNode(Uri.parse(url)) } | |
// Create a SOCKS proxy to connect to Tor and build an instance | |
// of OkHttpClient using the proxy. | |
val proxy = Proxy(Proxy.Type.SOCKS, InetSocketAddress.createUnresolved("localhost", 9050)) | |
val okHttpClient = OkHttpClient().newBuilder().proxy(proxy).build() | |
// Restore a MAINNET wallet by providing the secret key and creation date. | |
// For an offline wallet, set client parameter to null. | |
val wallet = provider.restoreWallet( | |
network = MoneroNetwork.Mainnet, | |
client = RpcClient.forNetwork( | |
MoneroNetwork.Mainnet, | |
remoteNodes = flowOf(torNodes), // API expects a flow of nodes. Using a static list here for simplicity. | |
loadBalancerRule = RoundRobinRule(), | |
httpClient = okHttpClient | |
), | |
secretSpendKey = SecretKey("d2ca26e22489bd9871c910c58dee3ab08e66b9d566825a064c8c0af061cd8706".parseHex()), | |
accountCreationTime = Instant.parse("2017-12-03T10:15:30.00Z") | |
) | |
// Print the primary address of the wallet. | |
println("New wallet address is ${wallet.primaryAddress}") | |
// Implement the simple storage for the wallet using an AtomicFile named "unencrypted.wallet". | |
// A real app should add its wallet encryption layer here. | |
wallet.dataStore = object : WalletDataStore { | |
private val file: AtomicFile = AtomicFile(File("unencrypted.wallet")) | |
override suspend fun write(writer: (FileOutputStream) -> Unit) = | |
file.startWrite().use { output -> | |
writer(output) | |
file.finishWrite(output) | |
} | |
override suspend fun read(): FileInputStream = file.openRead() | |
} | |
// Auto-save the wallet every 1 minute. | |
launch { | |
while (isActive) { | |
wallet.commit() | |
delay(60.seconds) | |
} | |
} | |
// Start listening to balance updates. | |
launch { | |
// The Ledger is an immutable object that contains a balance query object | |
// and the list of owned transactions detected so far. | |
wallet.ledger().collect { ledger -> | |
// When an update is received, print the height and total balance. | |
val amountFormatted = MoneroCurrency.format(ledger.balance.totalAmount) | |
val height = ledger.checkedAtBlockHeight | |
println("Balance @ block height $height: XMR $amountFormatted") | |
} | |
} | |
// Continuously refresh the wallet by calling awaitRefresh() until it receives an error. | |
// Refreshing does not block the wallet. Other functions like commit() can be called simultaneously. | |
val syncJob = launch { | |
while (isActive) { | |
val result = wallet.awaitRefresh() | |
if (result.isError()) { | |
cancel("Error syncing the wallet") | |
} | |
// Prints the block height and waits 15 seconds before refreshing again. | |
println("Refresh done. Height: ${result.blockHeight}") | |
delay(15.seconds) | |
} | |
} | |
// Wait until scope is canceled. | |
syncJob.join() | |
// Close the wallet | |
wallet.close() | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment