Skip to content

Update sideshift plugin with new optional API fields#218

Merged
j0ntz merged 1 commit into
masterfrom
jon/merge-sideshift-pr
Jul 13, 2026
Merged

Update sideshift plugin with new optional API fields#218
j0ntz merged 1 commit into
masterfrom
jon/merge-sideshift-pr

Conversation

@j0ntz

@j0ntz j0ntz commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

CHANGELOG

Does this branch warrant an entry to the CHANGELOG?

  • Yes
  • No

Dependencies

none

Description

Recreates external fork PR #208 ("Update sideshift plugin") on a fresh branch off current master. The original PR is from a fork (popfendi) and is in a CONFLICTING state because master evolved since it was opened (the StandardTx shape and the asSideshiftTx cleaner both gained fields). This re-applies the partner's change cleanly onto current master.

Sideshift's API now returns additional optional fields: settledAt, depositContractAddress, settleContractAddress, depositHash, settleHash, depositEvmChainId, settleEvmChainId. This change:

  • Captures all of the above in the asSideshiftTx cleaner (asOptional).
  • Wires depositTxid from tx.depositHash and payoutTxid from tx.settleHash in processSideshiftTx.

Per the partner's note, the remaining new fields (contract addresses, EVM chain IDs, settledAt) are intentionally captured on rawTx for use where needed and are not yet mapped to StandardTx output.

Asana: https://app.asana.com/0/1215088146871429/1214638405678783

Testing

  • npm run build.types (tsc), npm run build.lib, and npm run build.dist pass with the change (verified locally via npm run prepare; only the setup step, which requires a live CouchDB, could not run in the agent sandbox).
  • Full live integration against a CouchDB instance populated with live Sideshift data was not possible in the agent environment (no CouchDB / Sideshift credentials). Recommend a maintainer run the live couch test before merge.

Note

Medium Risk
Reporting semantics change (txids now populated from partner hashes) with a documented caveat that deposit hashes may not be customer payments; existing Couch txs may be rewritten when hashes arrive on re-query.

Overview
Extends the SideShift partner integration for new optional API fields (depositHash, settleHash, contract addresses, EVM chain IDs, settledAt) and wires depositTxid / payoutTxid from the hash fields instead of leaving them unset.

depositEvmChainId / settleEvmChainId use asMaybe(asNumber) so bad encodings do not fail an entire query window. Contract addresses and settledAt stay on rawTx only for now. A code comment notes that depositHash may be SideShift’s internal sweep tx, not the user’s deposit, on several chain types.

The query engine’s checkUpdateTx now treats depositTxid and payoutTxid as updatable fields so Couch documents refresh when hashes appear or change on later polls.

Reviewed by Cursor Bugbot for commit 3efce41. Bugbot is set up for automated code reviews on this repo. Configure here.

@j0ntz

j0ntz commented Jul 9, 2026

Copy link
Copy Markdown
Contributor Author

Code review

Found 3 issues:

  1. depositTxid is wired from tx.depositHash, which SideShift's docs describe as the internal sweep-transaction hash (deposit contract to SideShift's own wallet) on EVM chains, TRON, Aptos, Sui, NEAR, and Algorand, not the customer's original deposit transaction. Any consumer using depositTxid to trace what the customer actually sent follows the wrong on-chain transaction for these networks.

countryCode: null,
depositTxid: tx.depositHash,
depositAddress,

  1. checkUpdateTx's tracked-field list omits depositTxid/payoutTxid, so once a doc is stored without these hashes, a later poll that fills them in but doesn't change status/chainPluginId/evmChainId/tokenId computes zero changed fields and the update is skipped. The backfill this PR adds can silently never persist.

const checkUpdateTx = (oldTx: StandardTx, newTx: StandardTx): string[] => {
const fields = [
'status',
'depositChainPluginId',
'depositEvmChainId',
'depositTokenId',
'payoutChainPluginId',
'payoutEvmChainId',
'payoutTokenId'
] as const
const changedFields: string[] = []
for (const field of fields) {

  1. Lower confidence: depositEvmChainId/settleEvmChainId are cleaned with the strict asOptional(asNumber). If SideShift ever returns either as a numeric string, asSideshiftTx throws, the error escapes processSideshiftTx into the outer retry loop, and the whole 5-day time block is retried then abandoned, dropping every order in that block instead of just the one bad record. Both fields are otherwise unused (the raw payload is already preserved via rawTx).

depositHash: asOptional(asString),
depositContractAddress: asOptional(asString),
depositEvmChainId: asOptional(asNumber),
invoiceAmount: asString,
settleAddress: asObject({
address: asString
}),
settleAmount: asString,
settleAsset: asString,
settleNetwork: asOptional(asString),
settleHash: asOptional(asString),
settleContractAddress: asOptional(asString),
settleEvmChainId: asOptional(asNumber),
createdAt: asString,

🤖 Generated with Claude Code

- If this code review was useful, please react with 👍. Otherwise, react with 👎.

@j0ntz

j0ntz commented Jul 9, 2026

Copy link
Copy Markdown
Contributor Author

Addressed the review findings above (fixup commits pushed):

  • Finding 2 (checkUpdateTx omits depositTxid/payoutTxid): fixed. Both fields added to the tracked-field list in checkUpdateTx, so a later poll that backfills either hash now persists the update.
  • Finding 3 (strict asOptional(asNumber) on depositEvmChainId/settleEvmChainId): fixed. Both now use asMaybe(asNumber), so an unexpected encoding degrades to undefined instead of throwing and aborting the whole 5-day query block.
  • Finding 1 (depositTxid = SideShift sweep hash on EVM/TRON/Aptos/Sui/NEAR/Algorand): acknowledged, not changed. The API exposes no field carrying the customer's own deposit transaction on those networks, so depositHash is the best available reference. A code comment now documents that depositTxid is an order reference, not a pointer to the customer's on-chain payment, so downstream consumers don't misuse it.

@j0ntz
j0ntz force-pushed the jon/merge-sideshift-pr branch from 18bdef5 to e85ca8c Compare July 9, 2026 17:59
Sideshift's API now returns optional settledAt, deposit/settle contract
addresses, deposit/settle hashes, and deposit/settle EVM chain IDs. Capture
these in the asSideshiftTx cleaner and wire depositTxid/payoutTxid from the
new deposit/settle hashes. The remaining new fields are available on rawTx.

Recreates #208 (external fork PR) onto current
master.
@j0ntz
j0ntz force-pushed the jon/merge-sideshift-pr branch from e85ca8c to 3efce41 Compare July 11, 2026 01:56

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 3efce41. Configure here.

Comment thread src/partners/sideshift.ts
// their wallet), not the customer's own deposit transaction. The API
// exposes no better field, so treat this as an order reference, not a
// pointer to the customer's on-chain payment.
depositTxid: tx.depositHash,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Wrong hash in depositTxid

Medium Severity

depositTxid is set from tx.depositHash, which on EVM, TRON, Aptos, Sui, NEAR, and Algorand is SideShift’s internal sweep (deposit contract → their wallet), not the customer’s deposit. Other plugins treat depositTxid as the customer pay-in hash, so consumers tracing the user’s on-chain payment follow the wrong transaction for those networks. Leaving it unset was more accurate than storing a misleading hash.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 3efce41. Configure here.

@j0ntz
j0ntz merged commit d9c6f34 into master Jul 13, 2026
5 checks passed
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.

2 participants