-
-
Notifications
You must be signed in to change notification settings - Fork 218
[cdk]: fix(cashu): apply P2PK conditions in CDK send #3616
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: cdk
Are you sure you want to change the base?
Conversation
Summary of ChangesHello @ajaysehwal, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request enhances the Cashu Dev Kit (CDK) by adding support for P2PK spending conditions, allowing users to lock tokens to a specific public key. This adds a layer of security and control over token spending. The changes include updates to the Android and iOS modules to handle the new conditions, as well as improvements to error handling to provide more informative error messages to the user. Highlights
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code Review
This pull request correctly implements P2PK spending conditions for Cashu sends, ensuring consistency across both Android and iOS platforms. The changes also include necessary updates to the TypeScript store to prepare the condition data and handle a new error case related to P2PK-locked tokens. My review includes a couple of suggestions to improve code clarity and robustness in the Kotlin implementation and to simplify an error-checking condition in the TypeScript code.
| var includeFee = false | ||
| var conditions: SpendingConditions? = null | ||
| if (optionsJson != null) { | ||
| val parsed = JSONObject(optionsJson) | ||
| includeFee = parsed.optBoolean("include_fee", false) | ||
|
|
||
| // Parse spending conditions (P2PK) if provided | ||
| if (parsed.has("conditions") && !parsed.isNull("conditions")) { | ||
| val cond = parsed.getJSONObject("conditions") | ||
| val kind = cond.optString("kind") | ||
| if (kind == "P2PK" && cond.has("data")) { | ||
| val data = cond.getJSONObject("data") | ||
| val pubkeyHex = data.getString("pubkey") | ||
| val locktime = | ||
| if (data.has("locktime") && !data.isNull("locktime")) | ||
| data.getLong("locktime").toULong() | ||
| else null | ||
| val refundKeysJson = data.optJSONArray("refund_keys") | ||
| val refundKeys = refundKeysJson?.let { arr -> | ||
| (0 until arr.length()).mapNotNull { i -> | ||
| try { arr.getString(i) } catch (e: Exception) { null } | ||
| } | ||
| } | ||
|
|
||
| conditions = SpendingConditions.P2pk( | ||
| pubkey = pubkeyHex, | ||
| conditions = Conditions( | ||
| locktime = locktime ?: 0UL, | ||
| pubkeys = emptyList(), | ||
| refundKeys = refundKeys ?: emptyList(), | ||
| numSigs = 0UL, | ||
| sigFlag = 0.toUByte(), | ||
| numSigsRefund = 0UL | ||
| ) | ||
| ) | ||
| } | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The logic for parsing spending conditions is quite nested and could be made more robust. Using optJSONObject with let blocks would flatten the structure, improve readability, and prevent potential JSONExceptions from malformed optionsJson. This would also align the implementation more closely with the safer, optional-chaining approach used in the Swift counterpart.
var includeFee = false
var conditions: SpendingConditions? = null
optionsJson?.let {
val parsed = JSONObject(it)
includeFee = parsed.optBoolean("include_fee", false)
// Parse spending conditions (P2PK) if provided
parsed.optJSONObject("conditions")?.let { cond ->
if (cond.optString("kind") != "P2PK") return@let
cond.optJSONObject("data")?.let { data ->
val pubkeyHex = data.optString("pubkey").takeIf { it.isNotEmpty() } ?: return@let
val locktime = if (data.has("locktime") && !data.isNull("locktime")) {
data.optLong("locktime").toULong()
} else {
null
}
val refundKeys = data.optJSONArray("refund_keys")?.let { arr ->
(0 until arr.length()).mapNotNull { i ->
arr.optString(i).takeIf { it.isNotEmpty() }
}
}
conditions = SpendingConditions.P2pk(
pubkey = pubkeyHex,
conditions = Conditions(
locktime = locktime ?: 0UL,
pubkeys = emptyList(),
refundKeys = refundKeys ?: emptyList(),
numSigs = 0UL,
sigFlag = 0.toUByte(),
numSigsRefund = 0UL
)
)
}
}
}There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
solid suggestion
| if ( | ||
| e?.message?.includes('Witness is missing for p2pk signature') || | ||
| (typeof e?.message === 'string' && | ||
| e.message.toLowerCase().includes('witness is missing') && | ||
| e.message.toLowerCase().includes('p2pk')) | ||
| ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The condition to check for the 'witness is missing' error is a bit verbose. The second part of the || condition is a more robust, case-insensitive check that makes the first part redundant. Simplifying this will make the code cleaner and easier to maintain.
if (
typeof e?.message === 'string' &&
e.message.toLowerCase().includes('witness is missing') &&
e.message.toLowerCase().includes('p2pk')
) {There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Solid suggestion
d3459e1 to
4f7e530
Compare
7003395 to
7ba4b33
Compare
7ba4b33 to
6d5f7ba
Compare
| this.error_msg = undefined; | ||
| }); | ||
|
|
||
| console.log('mintToken', memo, value, pubkey, lockTime); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove this log
| data: conditionData | ||
| }; | ||
| } | ||
| console.log('conditions', conditions); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove log
| const mintUrl = this.selectedMintUrl; | ||
|
|
||
| try { | ||
| await this.syncCDKBalances(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why do we need to sync balances here?
|
After changes above, be sure to test on Android again at the very least after the native code changes |
Description
Relates to issue: ZEUS-3614 & #3614 (review)
Please enter a description and screenshots, if appropriate, of the work covered in this PR
This pull request is categorized as a:
Checklist
yarn run tscand made sure my code compiles correctlyyarn run lintand made sure my code didn’t contain any problematic patternsyarn run prettierand made sure my code is formatted correctlyyarn run testand made sure all of the tests passTesting
If you modified or added a utility file, did you add new unit tests?
I have tested this PR on the following platforms (please specify OS version and phone model/VM):
I have tested this PR with the following types of nodes (please specify node version and API version where appropriate):
Locales
Third Party Dependencies and Packages
yarnafter this PR is merged inpackage.jsonandyarn.lockhave been properly updatedOther: