thenewboston-blockchain / kotlin-sdk Goto Github PK
View Code? Open in Web Editor NEWKotlin-SDK for thenewboston.
Home Page: https://thenewboston.com
License: MIT License
Kotlin-SDK for thenewboston.
Home Page: https://thenewboston.com
License: MIT License
Check the Account-Manager for further information
AS an SDK user
I WANT to update the network to remove any disconnected nodes
SO THAT the network is kept updated.
Description
Implement POST request in BankDataSource
and expose the function in BankRepository
Please write unit tests to cover cases.
Documentation - https://thenewboston.com/bank-api/clean
As an SDK user,
I WANT
To be able to fetch all the bank's configuration details
SO THAT
I can I know who is the primary validator of the bank and other connection settings to properly connect to the bank.
Documentation for bank transactions endpoints for GET requests https://thenewboston.com/bank-api/config
Tech notes:
Endpoint -> http://143.110.137.54/config
From the discuss in #46 We decided to go with Kotest.
Instead of the less powerful JUnit default assertions, we should integrate a proper assertions library for more idiomatic and readable tests.
Possible assertion libraries include...
Kotest assertions
AssertJ
Strikt
There isn't a huge number of test cases yet so we still have the opportunity to refactor them to the syntax of the assertion library and make them consistent without super huge effort. This would be a good addition.
a PR shouldn't be mergeable if the unit tests within the branch fail
AS a developer
I WANT
To be able to see how much of my code is covered by unit tests when submitting a PR.
SO THAT
I can merge my code to master with high test coverage.
Description:
We need to introduce quality gates on sonarqube so that we can ensure high test coverage on new code and the master branch.
We need to define quality gates definition on previous versions which scans new code:
https://sonarcloud.io/documentation/user-guide/new-code/
The default sonarqube quality gate is 80% and this is what we will use.
We have defined the version in the sonar.gradle property "sonar.projectVersion", "1.0.0"
Every time we increment the version a new report is generated and it gets tagged. e.g. 1.1.0 is tagged in the console with the code quality gate.
AS a developer
I WANT an SDK user to send us their ip address, port and protocol
SO THAT we avoid hardcoding a single bank's details.
Description:
Since we are using the BankConfig data class with a hardcoded bank details, we need to allow the SDK users to pass in their own setup. We can simply do this with our TNBSDKBuilder class to send us a Config object.
data class Config( val ipAddress: String val port: Int, val protocol: String )
In the TNBSDKBuilder:
class TNBSDKBuilder(private val config: Config) {
//..
class Builder {
private lateinit var config: Config
fun withBankConfig(config: Config) = apply { this.config = config }
fun buildBanksRepository(): BankRepository {
val builder = TNBSDKBuilder(config)
return builder.initBankRepository()
}
}
}
Right now we're using Java's Date library which is deprecated. This issue is about introducing a full Kotlin date api and swap the current dates we have.
@akulinski mentioned https://github.com/Kotlin/kotlinx-datetime which looks interesting
@MrIceman "We’ll need a 100% kotlin persistance library / api to save bank / validator configs on disk. Any suggestions?"
Started this issue to discuss any persistence libraries that supports Kotlin.
As discussed in the slack thread there are 2 promising libraries for SQL and NoSQL.
SQLDelight which generates type safe Kotlin APIs from SQL.
https://github.com/cashapp/sqldelight
A new kid on the block which is a No SQL persistence library created by Kodein.
https://github.com/Kodein-Framework/Kodein-DB
As an SDK user,
I WANT
To be able to fetch all the bank's configuration details
SO THAT
I can I know who is the primary validator of the bank and other connection settings to properly connect to the bank.
Documentation for bank transactions endpoints for GET requests https://thenewboston.com/bank-api/config
Tech notes:
Endpoint -> http://143.110.137.54/config
Hello guys, the tabs on the top right corner of the landing page needs to be reverted to the old design where "Leaderboard", "Tasks", "Openings", "Docs", "Help" was shown as this is more navigable for first time visitors to the site. The design of the site is already simplistic enough and i don't think there should be a need for dropdown menus for the above listed tabs/pages.I watched 'bucky's - hello world' video and the design there is beautiful.
_If there is a need for more menus then i suggest a drop-down menu titled "discover" should be used as this is more engaging for a user.
Viewers watching that bucky's hello world video then navigating to the site might find it different if you know what i mean.
Add implementation from https://github.com/thenewboston-developers/Account-Manager/blob/c4a568752f3ff1b667b35b54152d0444137eaf8c/src/renderer/types/app.ts#L7 for kotlin SDK
AS an SDK user and a bank
I WANT
To see all the signed agreements between the bank and a confirmation validator
SO THAT
A confirmation validator will sign and send all confirmed blocks to the bank for a specified period of time.
Documentation - https://thenewboston.com/bank-api/validator-confirmation-services
Tech Notes
Implement the GET request in the BankDataSource and then expose the function in BankRepository
AS an SDK user and a bank
I WANT
To purchase confirmation services from a confirmation validator
SO THAT
A confirmation validator will get paid a transaction fee for confirming a block on the network.
Documentation - https://thenewboston.com/bank-api/validator-confirmation-services
Tech Notes
Implement the POST request in the BankDataSource and then expose the function in BankRepository
I think we should agree upon a data type for points (i.e. balances, amounts, transaction fees and confirmation rates) and use it consistently across the project.
Currently, there are 3 types being used: Number
, Double
, BigDecimal
.
However, points are actually whole numbers (example) - it's just the documentation that has not been updated - with a max value of 281_474_976_710_656
(see here)
So, I guess we should switch to java.math.BigInteger
?
https://github.com/detekt/detekt
Additional to ktlint detekt checks code for complexity and makes the developer aware if his code could be simpler.
This task is about introducing detekt and add it to the github actions script (consult @akulinski if you have questions about it)
AS a developer
I WANT useful abstractions
SO THAT we encapsulate similarities and avoid duplication.
Description:
It looks like all POST and PUT requests in the Bank API have the same root-level structure:
{
"message": { <different structure depending on request> },
"node_identifier": ...,
"signature": ...
}
Thus, we should extract a generic type that represents this structure, and allows inserting different types of messages. Also, we should adjust or remove any redundant DTOs.
The only exception I can see is /blocks, which has an account_number
instead of node_identifier
.
AS an SDK user and a bank
I WANT
To notify an upgrade in the case a confirmation validator has upgraded to a primary validator
SO THAT
I can send out an upgrade notice to all connected banks.
Documentation - https://thenewboston.com/bank-api/upgrade-notice
Tech Notes
Implement the POST request in the BankDataSource and then expose the function in BankRepository
AS an SDK user
I WANT to update the network to remove any disconnected nodes
SO THAT the network is kept updated.
Description
Implement GET request in BankDataSource
and expose the function in BankRepository
Please write unit tests to cover cases.
Documentation - https://thenewboston.com/bank-api/clean
AS an SDK user and a bank
I WANT
To connect with another node on the network,
SO THAT
A signed connection request can be sent to the target node.
Documentation - https://thenewboston.com/bank-api/connection-requests
Tech Notes
Implement the POST request in the BankDataSource and then expose the function in BankRepository
AS a developer
I WANT to avoid duplication
SO THAT we avoid maintenance costs and unnecessary bugs
Description:
Currently, there's a DTO BankTrustResponse
to represent the response of the PATCH request documented here: https://thenewboston.com/bank-api/banks.
As far as I can tell, that response is simply a Bank
, so we can remove the duplication. In fact, this is hopefully the case for all PATCH requests if the API is consistent (it is for Account
).
Also, the BankTrustResponse
is missing the version
field which Bank
correctly contains. Typical duplication bug :)
As an developer,
I WANT
To be able to know what the level of unit test coverage is and automate any potential code smells in PRs.
SO THAT
We can fail any builds that does not meet the expected code coverage and code quality level.
We currently have a github actions workflow so it's just the matter of using the SonarQube gradle plugin to hook it up. https://sonarcloud.io/ is what we need since it's free for open source projects
The JSON of each response the API offers should have an equivalent Data Model (DataTransferObject).
E.g. https://www.thenewboston.com/bank-api/accounts
GET /accounts returns
{
"id": "9eca00a5-d925-454c-a8d6-ecbb26ec2f76",
"created_date": "2020-07-08T02:14:59.307535Z",
"modified_date": "2020-07-08T02:14:59.307553Z",
"account_number": "4d2ec91f37bc553bc538e91195669b666e26b2ea3e4e31507e38102a758d4f86",
"trust": "75.21"
}
the equivalent would be
data class AccountsDTO(val id: String, val createdDate: Date, val modifiedDate: Date, val accountNumber: String, val trust: String)
This issue is about creating a DTO for every API Response. These dtos will serve as models when building the http laye
AS an SDK user
I WANT
To be able to send a block as a bank via the network
SO THAT
The primary validators and confirmation validators can use to verify the block and earn my transaction fee.
API Documentation - https://thenewboston.com/bank-api/blocks
Implement the POST request in the BankDataSource and then expose the function in BankRepository
As an SDK developer,
I WANT
To be able to unit test my API requests in isolation
SO THAT
I mock my API requests without affecting the production environment
We need to start using a Http client mock engine to mock our API requests in our data sources. There is a mock engine we can use for our Ktor Http Client to resolve this.
AS an SDK user and a confirmation validator
I WANT
To be send information about an invalid block to the bank that was verified by a primary validator
SO THAT
I know the block is invalid and I can decrease the trust of my primary validator and or elect a new one.
Documentation - https://thenewboston.com/bank-api/invalid-blocks
Implement the POST request in the BankDataSource and then expose the function in BankRepository
Since we want our Kotlin SDK to be used in Android and Desktop, a sample app would be ideal for testing integrations. Ideally when the Kotlin SDK has matured we can start adopting Kotlin Multiplatform Mobile for our SDK. This can allow us to distribute to Android and iOS applications.
For the moment, the sample doesn't have to be anything fancy and you can use the account manager as an ideal start for designing the sample app. The core functionality we would like is to see all the banks, active validators and your account.
As an SDK user,
I WANT
To be able to fetch all the available banks and also determine the level trust of the bank has.
SO THAT
I know which bank I can send transactions.
With the completion of the BankDataSource (#17). We can be also to expose the response in a repository back to the SDK users.
In order to build the architecture properly the domains of the system need to be defined first, e.g.
Once this is done we can start building the data and domain layers for each domain
As an SDK user,
I WANT
To be able to fetch all the bank's transactions
SO THAT
I can view a transaction within a block
Documentation for bank transactions endpoints for GET requests https://thenewboston.com/bank-api/bank-transactions
Tech notes:
Endpoint -> http://143.110.137.54/bank_transactions
As an SDK user,
I WANT
To be able to fetch all the available banks and also determine the level trust of the bank has.
SO THAT
I know which bank I can send transactions to.
Documentation for bank endpoints for GET and PATCH requests https://thenewboston.com/bank-api/banks
The data models and http layer are already implemented and just needs a data source class to call the endpoints.
As an SDK user,
I WANT
To be able to fetch all the bank's transactions
SO THAT
I can view a transaction within a block
Documentation for bank transactions endpoints for GET requests https://thenewboston.com/bank-api/bank-transactions
Tech notes:
Endpoint -> http://143.110.137.54/bank_transactions
AS an SDK user and a bank
I WANT
To be send information the network about an account
SO THAT
I can assign a trust level to each account
Documentation - https://thenewboston.com/bank-api/accounts
Implement the PATCH request in the BankDataSource and then expose the function in BankRepository
AS an SDK user
I WANT
To be able to fetch all the blocks on the network for a bank
SO THAT
I can see multiple transactions to different recipients within a single block.
API Documentation - https://thenewboston.com/bank-api/blocks
Implement the GET request in the BankDataSource
and then expose the function in BankRepository
I have realized that some portions of the code are using Gson whilst others are also using kotlinx.serialization
. Which serialization framework will we be working with in the future, is it going to be gson or kotlinx.serialization
because obviously we can't use both.
And this is using kotlinx.serialization
https://github.com/thenewboston-developers/Kotlin-SDK/blob/95d718f310b1b3cd8e78a9bf4caf4a1f03fcac75/lib/src/main/java/com/thenewboston/account/model/Account.kt
It would generally be a good practice to annotate all DTO fields in case the underlying API needs to change sometime in the future. When this happens only the annotation parameter will be changed instead of all instance of the field usages.
For example, this DTO data class
data class ConfigDTO(
@SerializedName("primary_validator")
val primaryValidator: PrimaryValidator,
@SerializedName("account_number")
val accountNumber: String,
@SerializedName("ip_address")
val ipAddress: String,
@SerializedName("node_identifier")
val nodeIdentifier: String,
val port: Int,
val protocol: String,
val version: String,
@SerializedName("default_transaction_fee")
val defaultTransactionFee: Double,
@SerializedName("node_type")
val nodeType: String
)
can be annotated fullly as,
data class ConfigDTO(
@SerializedName("primary_validator")
val primaryValidator: PrimaryValidator,
@SerializedName("account_number")
val accountNumber: String,
@SerializedName("ip_address")
val ipAddress: String,
@SerializedName("node_identifier")
val nodeIdentifier: String,
@SerializedName("port")
val port: Int,
@SerializedName("protocol")
val protocol: String,
@SerializedName("version")
val version: String,
@SerializedName("default_transaction_fee")
val defaultTransactionFee: Double,
@SerializedName("node_type")
val nodeType: String
)
This adds some extra work but I believe it is worth it.
AS an SDK user
I WANT to browse nodes on the network to discover any new ones
SO THAT I know the node's signing key
Description
Implement GET request in BankDataSource
and expose the function in BankRepository
Please write unit tests to cover cases.
Documentation - https://thenewboston.com/bank-api/crawl
AS an SDK user
I WANT
To be able to let other banks know how trustworthy a bank is.
SO THAT
I can assign the trust level to a bank
API Documentation - https://thenewboston.com/bank-api/banks
Implement the PATCH request in the BankDataSource and then expose the function in BankRepository
Instead of the less powerful JUnit default assertions, we should integrate a proper assertions library for more idiomatic and readable tests.
Possible assertion libraries include...
There isn't a huge number of test cases yet so we still have the opportunity to refactor them to the syntax of the assertion library and make them consistent without super huge effort. This would be a good addition.
AS an SDK user and a bank
I WANT
To be see if a block is invalid that is sent from the confirmation validator that had been received by a primary validator.
SO THAT
I know a block is invalid and I can decrease the trust of my primary validator
Documentation - https://thenewboston.com/bank-api/invalid-blocks
Implement the GET request in the BankDataSource
and then expose the function in BankRepository
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.