Skip to content

Conversation

@louisinger
Copy link
Contributor

@louisinger louisinger commented Sep 29, 2025

implements arkade-os/arkd#722

@altafan please review

Summary by CodeRabbit

  • New Features

    • Introduced intent-based proof model for RegisterIntent/DeleteIntent (proof + message).
  • Refactor

    • Replaced BIP322 signature flow with intent-based flow across SDK and clients.
    • Public client methods now use (proof, message) parameter naming.
  • API/Spec

    • OpenAPI updated: added Intent type, removed legacy Bip322Signature.
    • REST/GRPC payloads now send Intent {proof, message}.
  • Chores

    • Bumped ark-lib dependency version.

@coderabbitai
Copy link

coderabbitai bot commented Sep 29, 2025

Walkthrough

Replaces BIP322 signature types and flow with an intent-based proof across API spec, generated REST models, SDK signing/building logic, and transports. Introduces V1Intent (message, proof), replaces v1Bip322Signature, refactors signing to use intent.Input and arkFields, and updates buf/gomod inputs.

Changes

Cohort / File(s) Summary
API spec: switch to Intent
api-spec/openapi/swagger/ark/v1/service.swagger.json
Removes v1Bip322Signature; adds v1Intent; updates RegisterIntent/DeleteIntent request schemas to reference v1Intent (message, proof).
Generated REST models: intent model added / bip322 removed
client/rest/service/models/v1_intent.go, client/rest/service/models/v1_bip322_signature.go
Adds V1Intent (Message, Proof) with (de)serialization; deletes V1Bip322Signature and its helpers.
Generated REST models: request payloads updated
client/rest/service/models/v1_register_intent_request.go, client/rest/service/models/v1_delete_intent_request.go
V1RegisterIntentRequest and V1DeleteIntentRequest now reference *V1Intent (json field intent), validation/context validation updated accordingly.
SDK core: intent signing flow and helpers
client.go, utils.go
Replaces BIP322 paths with intent-based flow: toIntentInputs, makeIntent, makeRegisterIntent, makeDeleteIntent; inputs now []intent.Input; introduces arkFields ([][]*psbt.Unknown) propagated through signing and PSBT assembly; returns proofTx/message pairs.
Client interface: parameter rename
client/client.go
TransportClient public methods renamed parameter identifiers from signatureproof (types unchanged): RegisterIntent(ctx, proof, message) and DeleteIntent(ctx, proof, message).
gRPC transport: request shape & params
client/grpc/client.go
Client methods parameter renamed to (proof, message); gRPC requests now send arkv1.RegisterIntentRequest/DeleteIntentRequest carrying Intent{Message, Proof} instead of Bip322Signature.
REST transport: request shape & params
client/rest/client.go
Methods now accept (proof, message); HTTP request bodies use V1Intent{message, proof} instead of V1Bip322Signature.
Generated REST model: V1DeleteIntentRequest field rename
client/rest/service/models/v1_delete_intent_request.go
Field Proof *V1Bip322SignatureIntent *V1Intent and JSON key proofintent; validation helpers renamed.
Build/config
buf.gen.yaml
Changes inputs.git_repo branch from v0.7.1rcmaster (source for protobuf generation).
Dependency update
go.mod
Bumps github.com/arkade-os/arkd/pkg/ark-lib reference from commit 74f479373bc67f278b58e00f (version update).

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant App
  participant SDK as SDK (utils/client.go)
  participant Sign as Intent Signer
  participant Tx as PSBT/Tx Builder
  participant Transport as Transport (gRPC/REST)
  participant Arkd as Ark Service

  App->>SDK: RegisterIntent(opts, utxos, vtxos, notes)
  SDK->>SDK: toIntentInputs(...) → []intent.Input, leafProofs, arkFields
  SDK->>Tx: Build outputs (Receivers) → []*wire.TxOut
  SDK->>Sign: makeIntent(message, inputs, outputs, leafProofs, arkFields)
  Sign-->>SDK: proofTx, message
  SDK->>Transport: RegisterIntent(V1Intent{Message, Proof})
  Transport->>Arkd: arkv1.RegisterIntentRequest(intent)
  Arkd-->>Transport: intentId
  Transport-->>SDK: intentId
  SDK-->>App: intentId
Loading
sequenceDiagram
  autonumber
  participant App
  participant SDK as SDK (utils/client.go)
  participant Sign as Intent Signer
  participant Transport as Transport (gRPC/REST)
  participant Arkd as Ark Service

  App->>SDK: DeleteIntent(opts, inputs)
  SDK->>SDK: toIntentInputs(...) → []intent.Input, leafProofs, arkFields
  SDK->>Sign: makeIntent(deleteMessage, inputs, nil, leafProofs, arkFields)
  Sign-->>SDK: proofTx, message
  SDK->>Transport: DeleteIntent(V1Intent{Message, Proof})
  Transport->>Arkd: arkv1.DeleteIntentRequest(intent)
  Arkd-->>Transport: ok
  Transport-->>SDK: ok
  SDK-->>App: ok
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title “Intent proof of ownership rework” clearly refers to the primary change of migrating from BIP322 signatures to an intent-based proof mechanism, is concise and focused, and conveys the main purpose of the pull request without unnecessary detail.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ Finishing touches
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch intent-proof-rework

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 69d6602 and 7094f79.

⛔ Files ignored due to path filters (1)
  • go.sum is excluded by !**/*.sum
📒 Files selected for processing (2)
  • buf.gen.yaml (1 hunks)
  • go.mod (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • buf.gen.yaml
  • go.mod
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Sdk unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🧪 Early access (Sonnet 4.5): enabled

We are currently testing the Sonnet 4.5 model, which is expected to improve code review quality. However, this model may lead to increased noise levels in the review comments. Please disable the early access features if the noise level causes any inconvenience.

Note:

  • Public repositories are always opted into early access features.
  • You can enable or disable early access features from the CodeRabbit UI or by updating the CodeRabbit configuration file.

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (5)
api-spec/openapi/swagger/ark/v1/service.swagger.json (2)

54-62: Update DeleteIntent summary to match intent-proof model

Summary still references “BIP-322 signature” while the schema uses v1IntentProof. Replace text to avoid confusion.

Suggested edit:

  • “The client should provide an intent proof … including any of the vtxos … to prove ownership.”
  • Remove BIP‑322 mentions.

131-139: Update RegisterIntent summary away from BIP-322

This path still says “BIP‑322 message” but request now uses v1IntentProof. Align wording with the new flow.

Suggested edit:

  • “The client should provide an intent proof (message + proof) with the intent information …”
go.mod (1)

3-3: Invalid go directive: use minor only, move patch to toolchain

go 1.24.6 is not a valid go.mod directive. It must be go 1.24 (patch belongs in toolchain).

Apply:

-go 1.24.6
+go 1.24
+toolchain go1.24.6
client.go (2)

1882-1923: Guard against index panics and use ctx for signing.

proof.Inputs is offset by +1 versus actual inputs; current code assumes perfect lengths and can panic if slices mismatch. Add validations and sign with the caller’s ctx.

-func (a *arkClient) makeIntent(
-	message string, inputs []intent.Input, outputsTxOut []*wire.TxOut,
-	leafProofs []*arklib.TaprootMerkleProof, arkFields [][]*psbt.Unknown,
-) (string, string, error) {
-  proof, err := intent.New(message, inputs, outputsTxOut)
+func (a *arkClient) makeIntent(
+	ctx context.Context,
+	message string,
+	inputs []intent.Input,
+	outputsTxOut []*wire.TxOut,
+	leafProofs []*arklib.TaprootMerkleProof,
+	arkFields [][]*psbt.Unknown,
+) (string, string, error) {
+  proof, err := intent.New(message, inputs, outputsTxOut)
   if err != nil {
     return "", "", err
   }
 
+  // Expect: len(proof.Inputs) == len(leafProofs)+1 and len(arkFields) == len(leafProofs)
+  if len(leafProofs) == 0 {
+    return "", "", fmt.Errorf("makeIntent: no leaf proofs provided")
+  }
+  if len(proof.Inputs) != len(leafProofs)+1 {
+    return "", "", fmt.Errorf("makeIntent: mismatched inputs/proofs: inputs=%d proofs=%d (expected inputs=proofs+1)", len(proof.Inputs), len(leafProofs))
+  }
+  if len(arkFields) != len(leafProofs) {
+    return "", "", fmt.Errorf("makeIntent: arkFields length %d != leafProofs length %d", len(arkFields), len(leafProofs))
+  }
+
   for i, input := range proof.Inputs {
     // intent proof tx has an additional input using the first vtxo script
     // so we need to use the previous leaf proof for the current input except for the first input
     var leafProof *arklib.TaprootMerkleProof
     if i == 0 {
       leafProof = leafProofs[0]
     } else {
       leafProof = leafProofs[i-1]
-      input.Unknowns = arkFields[i-1]
+      input.Unknowns = arkFields[i-1]
     }
     input.TaprootLeafScript = []*psbt.TaprootTapLeafScript{
       {
         ControlBlock: leafProof.ControlBlock,
         Script:       leafProof.Script,
         LeafVersion:  txscript.BaseLeafVersion,
       },
     }
 
     proof.Inputs[i] = input
   }
 
-  unsignedProofTx, err := proof.B64Encode()
+  unsignedProofTx, err := proof.B64Encode()
   if err != nil {
     return "", "", err
   }
 
-  signedTx, err := a.wallet.SignTransaction(context.Background(), a.explorer, unsignedProofTx)
+  signedTx, err := a.wallet.SignTransaction(ctx, a.explorer, unsignedProofTx)
   if err != nil {
     return "", "", err
   }
 
   return signedTx, message, nil
 }

2037-2083: Rebuild proof/message per retry; fix “attempt” typo.

Reusing a prebuilt proof/message risks TTL expiry and stale inputs. Regenerate inside the loop; also fix the typo.

-  proofTx, message, err := a.makeRegisterIntent(
-    inputs, exitLeaves, outputs, signerPubKeys, arkFields,
-  )
-  if err != nil {
-    return "", err
-  }
-
   maxRetry := 3
   retryCount := 0
   var batchErr error
   for retryCount < maxRetry {
-    intentID, err := a.client.RegisterIntent(ctx, proofTx, message)
+    // Build a fresh proof/message each attempt to avoid TTL/skew issues.
+    proofTx, message, err := a.makeRegisterIntent(
+      ctx, inputs, exitLeaves, outputs, signerPubKeys, arkFields,
+    )
+    if err != nil {
+      return "", err
+    }
+    intentID, err := a.client.RegisterIntent(ctx, proofTx, message)
     if err != nil {
       return "", err
     }
@@
-  return "", fmt.Errorf("reached max atttempt of retries, last batch error: %s", batchErr)
+  return "", fmt.Errorf("reached max attempt of retries, last batch error: %s", batchErr)

Also update the earlier call to handleOptions to propagate ctx:

-  signerSessions, signerPubKeys, err := a.handleOptions(options, inputs, notes)
+  signerSessions, signerPubKeys, err := a.handleOptions(ctx, options, inputs, notes)
🧹 Nitpick comments (14)
api-spec/openapi/swagger/ark/v1/service.swagger.json (1)

648-651: Fix minor doc typo (“the the proof of funds”)

Remove the duplicated “the”.

Since this file is generated, fix the comment in the .proto and regenerate.

client/rest/client.go (1)

139-145: Switch to V1IntentProof is correct; add basic input validation.

Before sending the request, fail fast on empty proof/message to surface clearer client-side errors.

Apply diffs:

 func (a *restClient) RegisterIntent(
   ctx context.Context,
   proof, message string,
 ) (string, error) {
+  if proof == "" || message == "" {
+    return "", fmt.Errorf("proof and message are required")
+  }
   body := &models.V1RegisterIntentRequest{
     Intent: &models.V1IntentProof{
       Message: message,
       Proof:   proof,
     },
   }
-func (a *restClient) DeleteIntent(_ context.Context, proof, message string) error {
+func (a *restClient) DeleteIntent(_ context.Context, proof, message string) error {
+  if proof == "" || message == "" {
+    return fmt.Errorf("proof and message are required")
+  }
   body := &models.V1DeleteIntentRequest{
     Proof: &models.V1IntentProof{
       Message: message,
       Proof:   proof,
     },
   }

Also applies to: 157-162

client/rest/service/models/v1_intent_proof.go (1)

15-25: If message/proof are required, enforce via OpenAPI (don’t hand-edit generated code).

The generated type has no validations. If both fields are mandatory, mark them as required in the OpenAPI schema (and optionally add formats/patterns), then re-generate to get Validate/ContextValidate checks. This prevents accidental empty payloads early in clients.

Also applies to: 27-35

client/grpc/client.go (1)

150-156: Good migration to arkv1.IntentProof; add argument checks for clearer errors.

Validate inputs before RPC to return InvalidArgument instead of server-side failures.

Apply diffs:

 func (a *grpcClient) RegisterIntent(
   ctx context.Context,
   proof, message string,
 ) (string, error) {
+  if proof == "" || message == "" {
+    return "", status.Error(codes.InvalidArgument, "proof and message are required")
+  }
   req := &arkv1.RegisterIntentRequest{
     Intent: &arkv1.IntentProof{
       Message: message,
       Proof:   proof,
     },
   }
-func (a *grpcClient) DeleteIntent(ctx context.Context, proof, message string) error {
+func (a *grpcClient) DeleteIntent(ctx context.Context, proof, message string) error {
+  if proof == "" || message == "" {
+    return status.Error(codes.InvalidArgument, "proof and message are required")
+  }
   req := &arkv1.DeleteIntentRequest{
     Proof: &arkv1.IntentProof{
       Message: message,
       Proof:   proof,
     },
   }

Also applies to: 166-171

utils.go (4)

315-323: Return-shape clarity: document parallelism or introduce a small struct.

toIntentInputs returns inputs, exitLeaves, and arkFields as three parallel slices. Either document the 1:1 index relationship prominently here or return a slice of a small struct bundling these per-input fields to avoid accidental misalignment down the line.


394-399: Remove dead code around nextInputIndex.

nextInputIndex is computed and mutated but never used, which is confusing and risks future misuse.

Apply this diff:

-  nextInputIndex := len(inputs)
-  if nextInputIndex > 0 {
-    // if there is non-notes inputs, count the extra intent proof input
-    nextInputIndex++
-  }
@@
-    nextInputIndex++
-    // if the note vtxo is the first input, it will be used twice
-    if nextInputIndex == 1 {
-      nextInputIndex++
-    }

Also applies to: 438-443


406-419: Minor readability: avoid name collision with inputs; use a distinct identifier.

Rename the inner variable input to noteInput for clarity.

Apply this diff:

-  outpoint, input, err := parsedNote.IntentProofInput()
+  outpoint, noteInput, err := parsedNote.IntentProofInput()
@@
-  inputs = append(inputs, intent.Input{
+  inputs = append(inputs, intent.Input{
     OutPoint: outpoint,
     Sequence: wire.MaxTxInSequenceNum,
     WitnessUtxo: &wire.TxOut{
-      Value:    input.WitnessUtxo.Value,
-      PkScript: input.WitnessUtxo.PkScript,
+      Value:    noteInput.WitnessUtxo.Value,
+      PkScript: noteInput.WitnessUtxo.PkScript,
     },
   })
@@
-  arkFields = append(arkFields, input.Unknowns)
+  arkFields = append(arkFields, noteInput.Unknowns)

515-551: Rename unused inputs parameter to blank identifier
This removes the unused-parameter warning without touching call sites:

-func registerIntentMessage(
-    inputs []intent.Input, outputs []types.Receiver,
+func registerIntentMessage(
+    _ []intent.Input, outputs []types.Receiver,
     cosignersPublicKeys []string,
) (string, []*wire.TxOut, error) {
client.go (6)

1852-1864: Plumb context and delegate to makeIntent(ctx, ...).

Use the caller’s ctx for signing/cancellation and forward it to makeIntent.

-func (a *arkClient) makeRegisterIntent(
-	inputs []intent.Input, leafProofs []*arklib.TaprootMerkleProof,
-	outputs []types.Receiver, cosignersPublicKeys []string, arkFields [][]*psbt.Unknown,
-) (string, string, error) {
+func (a *arkClient) makeRegisterIntent(
+	ctx context.Context,
+	inputs []intent.Input,
+	leafProofs []*arklib.TaprootMerkleProof,
+	outputs []types.Receiver,
+	cosignersPublicKeys []string,
+	arkFields [][]*psbt.Unknown,
+) (string, string, error) {
   message, outputsTxOut, err := registerIntentMessage(
     inputs, outputs, cosignersPublicKeys,
   )
   if err != nil {
     return "", "", err
   }
-  return a.makeIntent(message, inputs, outputsTxOut, leafProofs, arkFields)
+  return a.makeIntent(ctx, message, inputs, outputsTxOut, leafProofs, arkFields)
 }

1866-1880: Make Delete TTL configurable and accept ctx.

Hardcoding 2 minutes may cause avoidable retries under load. Consider a default with override (option/env). Also pass ctx through.

-func (a *arkClient) makeDeleteIntent(
-	inputs []intent.Input, leafProofs []*arklib.TaprootMerkleProof, arkFields [][]*psbt.Unknown,
-) (string, string, error) {
+func (a *arkClient) makeDeleteIntent(
+	ctx context.Context,
+	inputs []intent.Input,
+	leafProofs []*arklib.TaprootMerkleProof,
+	arkFields [][]*psbt.Unknown,
+) (string, string, error) {
   message, err := intent.DeleteMessage{
     BaseMessage: intent.BaseMessage{
       Type: intent.IntentMessageTypeDelete,
     },
     ExpireAt: time.Now().Add(2 * time.Minute).Unix(),
   }.Encode()
   if err != nil {
     return "", "", err
   }
-  return a.makeIntent(message, inputs, nil, leafProofs, arkFields)
+  return a.makeIntent(ctx, message, inputs, nil, leafProofs, arkFields)
 }

942-949: Pass ctx into makeRegisterIntent after refactor.

-  proofTx, message, err := a.makeRegisterIntent(
-    inputs, exitLeaves, outputs, cosignersPublicKeys, arkFields,
-  )
+  proofTx, message, err := a.makeRegisterIntent(
+    ctx, inputs, exitLeaves, outputs, cosignersPublicKeys, arkFields,
+  )

967-973: Pass ctx into makeDeleteIntent after refactor.

-  proofTx, message, err := a.makeDeleteIntent(inputs, exitLeaves, arkFields)
+  proofTx, message, err := a.makeDeleteIntent(ctx, inputs, exitLeaves, arkFields)

2044-2047: Prefer ctx over Background for signer session creation.

Plumb ctx to handleOptions to allow cancellation/timeouts in wallet.NewVtxoTreeSigner.

-  signerSessions, signerPubKeys, err := a.handleOptions(options, inputs, notes)
+  signerSessions, signerPubKeys, err := a.handleOptions(ctx, options, inputs, notes)

2741-2775: handleOptions: accept ctx and avoid context.Background().

Use the caller’s ctx to bound wallet signer operations.

-func (a *arkClient) handleOptions(
-  options SettleOptions, inputs []intent.Input, notesInputs []string,
-) ([]tree.SignerSession, []string, error) {
+func (a *arkClient) handleOptions(
+  ctx context.Context,
+  options SettleOptions,
+  inputs []intent.Input,
+  notesInputs []string,
+) ([]tree.SignerSession, []string, error) {
@@
-    signerSession, err := a.wallet.NewVtxoTreeSigner(
-      context.Background(),
-      inputsToDerivationPath(outpoints, notesInputs),
-    )
+    signerSession, err := a.wallet.NewVtxoTreeSigner(
+      ctx,
+      inputsToDerivationPath(outpoints, notesInputs),
+    )
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 945cb4b and 79a3a34.

⛔ Files ignored due to path filters (3)
  • api-spec/protobuf/gen/ark/v1/service.pb.go is excluded by !**/*.pb.go, !**/gen/**
  • api-spec/protobuf/gen/ark/v1/types.pb.go is excluded by !**/*.pb.go, !**/gen/**
  • go.sum is excluded by !**/*.sum
📒 Files selected for processing (12)
  • api-spec/openapi/swagger/ark/v1/service.swagger.json (3 hunks)
  • buf.gen.yaml (1 hunks)
  • client.go (10 hunks)
  • client/client.go (1 hunks)
  • client/grpc/client.go (2 hunks)
  • client/rest/client.go (2 hunks)
  • client/rest/service/models/v1_bip322_signature.go (0 hunks)
  • client/rest/service/models/v1_delete_intent_request.go (1 hunks)
  • client/rest/service/models/v1_intent_proof.go (1 hunks)
  • client/rest/service/models/v1_register_intent_request.go (1 hunks)
  • go.mod (1 hunks)
  • utils.go (4 hunks)
💤 Files with no reviewable changes (1)
  • client/rest/service/models/v1_bip322_signature.go
🧰 Additional context used
🧬 Code graph analysis (6)
client/grpc/client.go (2)
api-spec/protobuf/gen/ark/v1/service.pb.go (6)
  • RegisterIntentRequest (209-216)
  • RegisterIntentRequest (229-229)
  • RegisterIntentRequest (244-246)
  • DeleteIntentRequest (299-306)
  • DeleteIntentRequest (319-319)
  • DeleteIntentRequest (334-336)
api-spec/protobuf/gen/ark/v1/types.pb.go (3)
  • IntentProof (441-447)
  • IntentProof (460-460)
  • IntentProof (475-477)
client/rest/client.go (3)
client/rest/service/models/v1_register_intent_request.go (1)
  • V1RegisterIntentRequest (19-24)
client/rest/service/models/v1_intent_proof.go (1)
  • V1IntentProof (18-25)
client/rest/service/models/v1_delete_intent_request.go (1)
  • V1DeleteIntentRequest (19-24)
client/rest/service/models/v1_register_intent_request.go (1)
client/rest/service/models/v1_intent_proof.go (1)
  • V1IntentProof (18-25)
utils.go (3)
types/types.go (2)
  • Utxo (208-219)
  • Receiver (229-232)
client/client.go (2)
  • TapscriptsVtxo (80-83)
  • Input (75-78)
api-spec/protobuf/gen/ark/v1/types.pb.go (6)
  • Input (76-82)
  • Input (95-95)
  • Input (110-112)
  • Tapscripts (397-402)
  • Tapscripts (415-415)
  • Tapscripts (430-432)
client/rest/service/models/v1_delete_intent_request.go (1)
client/rest/service/models/v1_intent_proof.go (1)
  • V1IntentProof (18-25)
client.go (3)
client/client.go (1)
  • Input (75-78)
api-spec/protobuf/gen/ark/v1/types.pb.go (3)
  • Input (76-82)
  • Input (95-95)
  • Input (110-112)
types/types.go (1)
  • Receiver (229-232)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Sdk unit tests
🔇 Additional comments (6)
buf.gen.yaml (1)

12-14: Pin buf input to a fixed commit SHA
Using a moving branch makes API generation nondeterministic—pin to the current intent-proof-rework commit:

 inputs:
   - git_repo: https://github.com/arkade-os/arkd.git
-    branch: intent-proof-rework
+    # branch: intent-proof-rework
+    revision: ff719d4e7b0f8d5ae1caa164adb4b373f7142d68

All specified proto files have been verified at this ref, ensuring reproducible codegen.

client/client.go (1)

22-23: LGTM: transport API aligns with intent-proof model.

RegisterIntent/DeleteIntent signatures look consistent with REST and gRPC clients returning intent ID and error.

utils.go (1)

347-356: Consistently attach Taproot tree metadata; errors are handled well.

Encoding the tap tree and placing it under VTXO_TAPROOT_TREE_KEY per input looks correct and mirrors both vtxos and boarding utxos.

Also applies to: 382-391

client.go (3)

17-17: Import looks good.

No action needed.


935-951: Intent inputs wiring LGTM; verify lengths before building proofs.

Looks correct to switch to toIntentInputs → makeRegisterIntent → client.RegisterIntent. Please ensure toIntentInputs guarantees:

  • len(exitLeaves) >= 1
  • len(arkFields) == len(exitLeaves)
  • len(inputs) >= 1

This prevents downstream index panics in makeIntent.


960-973: DeleteIntent flow LGTM; confirm notes-only edge cases.

If callers pass only notes (no vtxos/boarding UTXOs), verify toIntentInputs still returns consistent exitLeaves/arkFields to satisfy makeIntent’s expectations.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

♻️ Duplicate comments (4)
api-spec/openapi/swagger/ark/v1/service.swagger.json (2)

601-611: Make proof and message required; document encoding.

The v1Intent schema allows empty payloads because neither proof nor message is marked as required, and encoding guidance is missing. Without this, SDKs will not enforce presence or correct encoding at validation time.

As noted in the past review, update the source .proto to mark both fields as required (e.g., (google.api.field_behavior) = REQUIRED) and add clear encoding metadata in field descriptions (e.g., proof = base64, message = UTF-8/JSON), then regenerate the OpenAPI spec.


477-479: Require intent field in v1DeleteIntentRequest.

The intent field is optional in the schema, but DeleteIntent cannot proceed without proof. Mark it as required in the source proto and regenerate.

As noted in the past review, add "intent" to the required array in the v1DeleteIntentRequest definition in the source proto (e.g., (google.api.field_behavior) = REQUIRED) and regenerate the OpenAPI spec.

client/rest/service/models/v1_register_intent_request.go (1)

21-23: Require intent field in generated model.

The Intent field is optional (omitempty), but the API requires it. Mark it as required in the source proto and regenerate to remove omitempty and enforce validation.

As noted in the past review, update the source proto to mark intent as required (e.g., (google.api.field_behavior) = REQUIRED) and regenerate the SDK so the Go model enforces the field at validation time.

client/rest/service/models/v1_delete_intent_request.go (1)

21-23: Require intent field in generated model.

The Intent field is optional (omitempty), but DeleteIntent cannot proceed without proof. Mark it as required in the source proto and regenerate to enforce validation.

As noted in the past review, update the source proto to mark intent as required (e.g., (google.api.field_behavior) = REQUIRED) and regenerate the SDK so the Go model removes omitempty and enforces the field at validation time.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 79a3a34 and 69d6602.

⛔ Files ignored due to path filters (2)
  • api-spec/protobuf/gen/ark/v1/service.pb.go is excluded by !**/*.pb.go, !**/gen/**
  • api-spec/protobuf/gen/ark/v1/types.pb.go is excluded by !**/*.pb.go, !**/gen/**
📒 Files selected for processing (6)
  • api-spec/openapi/swagger/ark/v1/service.swagger.json (3 hunks)
  • client/grpc/client.go (2 hunks)
  • client/rest/client.go (2 hunks)
  • client/rest/service/models/v1_delete_intent_request.go (4 hunks)
  • client/rest/service/models/v1_intent.go (1 hunks)
  • client/rest/service/models/v1_register_intent_request.go (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • client/grpc/client.go
🧰 Additional context used
🧬 Code graph analysis (3)
client/rest/service/models/v1_register_intent_request.go (2)
api-spec/protobuf/gen/ark/v1/types.pb.go (3)
  • Intent (441-447)
  • Intent (460-460)
  • Intent (475-477)
client/rest/service/models/v1_intent.go (1)
  • V1Intent (18-25)
client/rest/service/models/v1_delete_intent_request.go (2)
api-spec/protobuf/gen/ark/v1/types.pb.go (3)
  • Intent (441-447)
  • Intent (460-460)
  • Intent (475-477)
client/rest/service/models/v1_intent.go (1)
  • V1Intent (18-25)
client/rest/client.go (4)
client/rest/service/models/v1_register_intent_request.go (1)
  • V1RegisterIntentRequest (19-24)
api-spec/protobuf/gen/ark/v1/types.pb.go (3)
  • Intent (441-447)
  • Intent (460-460)
  • Intent (475-477)
client/rest/service/models/v1_intent.go (1)
  • V1Intent (18-25)
client/rest/service/models/v1_delete_intent_request.go (1)
  • V1DeleteIntentRequest (19-24)
🔇 Additional comments (2)
client/rest/client.go (2)

137-155: RegisterIntent updated for intent-based flow.

The method signature and request body have been correctly updated to use the new V1Intent model with proof and message fields instead of the old BIP322 signature.


157-169: DeleteIntent updated for intent-based flow.

The method signature and request body have been correctly updated to use the new V1Intent model with proof and message fields instead of the old BIP322 signature.

@altafan altafan merged commit 8aeb354 into master Sep 30, 2025
3 checks passed
This was referenced Oct 4, 2025
@altafan altafan deleted the intent-proof-rework branch November 7, 2025 16:02
@coderabbitai coderabbitai bot mentioned this pull request Nov 25, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants