Skip to content

Conversation

@devin-ai-integration
Copy link
Contributor

@devin-ai-integration devin-ai-integration bot commented Dec 11, 2025

Summary

Adds an x-idempotency-key header with a unique UUID to requests made to the token transfer endpoint (/api/2025-06-09/wallets/{walletLocator}/tokens/{tokenLocator}/transfers). This prevents duplicate transaction creation when the same transfer request is accidentally sent multiple times.

Updates since last revision:

  • Exposed optional idempotencyKey parameter on Wallet.send() method, allowing callers to provide their own key for retry scenarios
  • If not provided, a random UUID is still generated automatically (backward compatible)
  • Updated SolanaDemo app with a 30-second rotating idempotency key to demonstrate usage

The implementation mirrors the approach taken in the Kotlin SDK (PR #45).

Test plan

  1. Make a token transfer request and verify the x-idempotency-key header is present in the outgoing request
  2. Verify the header value is a valid UUID format
  3. Test calling wallet.send() without providing idempotencyKey - should auto-generate a UUID
  4. Test calling wallet.send() with a custom idempotencyKey - should use the provided value
  5. Confirm the backend correctly handles the idempotency key for duplicate prevention

Review & Testing Checklist for Human

  • Verify the backend API expects the header name x-idempotency-key (lowercase) - confirm this matches the API specification
  • Confirm the 30-second rotation interval in the demo app aligns with the backend's idempotency window
  • Test a token transfer end-to-end to ensure the new optional parameter doesn't break existing functionality
  • Verify the SmartWalletsDemo (which uses the deprecated send API) still works correctly

Notes

@devin-ai-integration
Copy link
Contributor Author

Original prompt from [email protected]
Please add an x-idempotency-key header which is a unique key to prevent duplicate transaction creation to requests to the api/2025-06-09/wallets/{walletLocator}/tokens/{tokenLocator}/transfers endpoint (ie the transfer endpoint) in https://github.com/Crossmint/crossmint-swift-sdk

@devin-ai-integration
Copy link
Contributor Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment and CI monitoring

}
})
.onAppear {
startIdempotencyKeyRotation()
Copy link
Contributor

Choose a reason for hiding this comment

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

this hook can fire multiple times, might want to change to

idempotencyKeyTask?.cancel()
startIdempotencyKeyRotation()

to prevent multiple key rotation tasks

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good catch! Fixed - now cancelling any existing task before starting a new one in onAppear to prevent multiple rotation loops.

while !Task.isCancelled {
try? await Task.sleep(nanoseconds: 30_000_000_000)
await MainActor.run {
currentIdempotencyKey = UUID().uuidString
Copy link
Contributor

Choose a reason for hiding this comment

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

might want to also trigger changing currentIdempotencyKey any time recipient, token locator, or amount is changed

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Great suggestion! Added onChange handlers for amount, recipientWallet, and selectedToken that reset the idempotency key when any of these parameters change. This makes sense semantically since a different recipient/token/amount represents a new transaction that should have its own idempotency key.

Copy link
Contributor

@brendanw brendanw left a comment

Choose a reason for hiding this comment

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

looks good aside from minor comments

@tomas-martins-crossmint tomas-martins-crossmint merged commit ae5fc40 into main Dec 15, 2025
3 checks passed
@tomas-martins-crossmint tomas-martins-crossmint deleted the devin/1765466944-add-idempotency-key-to-transfers branch December 15, 2025 18:37
tomas-martins-crossmint added a commit that referenced this pull request Dec 15, 2025
…-sdk-coverage

Resolved conflicts by combining:
- Logging statements from current branch
- Idempotency key functionality from PR #41
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