Skip to content

feat: expose self-trade attributes in sharedlib and wasm bindings#76

Closed
mihaimarcu2004 wants to merge 1 commit into
self-tradefrom
devin/1780493092-wire-self-trade-sharedlib-wasm
Closed

feat: expose self-trade attributes in sharedlib and wasm bindings#76
mihaimarcu2004 wants to merge 1 commit into
self-tradefrom
devin/1780493092-wire-self-trade-sharedlib-wasm

Conversation

@mihaimarcu2004
Copy link
Copy Markdown
Contributor

@mihaimarcu2004 mihaimarcu2004 commented Jun 3, 2026

Summary

The self-trade branch (#75) added SelfTradeBehaviorMode, SelfTradeEqualityMode, and CancelAllMarketIndex to types.L2TxAttributes, but only at the types/txtypes layer — the C-FFI (sharedlib/main.go) and WASM (wasm/main.go) entrypoints had no way to set them. This PR wires those three attributes through both bindings via the existing attribute builders. Targets the self-trade branch since it depends on those type changes.

What's exposed where:

  • SignCreateOrder / SignCreateGroupedOrders / SignModifyOrder → new selfTradeBehaviorMode, selfTradeEqualityMode params
  • SignCancelAllOrders → new cancelAllMarketIndex param

Builders only set a pointer when the value differs from its nil/default (SelfTradeBehaviorExpireMaker=0, SelfTradeEqualityAccountIndex=0, NilMarketIndex=255), so passing defaults produces byte-identical signatures to before (verified: WASM SignCreateOrder still emits L2TxAttributes without keys 6/7).

// sharedlib
CreateIntegratorTxAttributes(..., skipNonce, selfTradeBehaviorMode, selfTradeEqualityMode)
CreateCancelAllTxAttributes(cancelAllMarketIndex, skipNonce)   // new helper
// wasm
integratorTxAttributes(..., skipNonce, selfTradeBehaviorMode, selfTradeEqualityMode)
cancelAllTxAttributes(cancelAllMarketIndex, skipNonce)         // new helper

New args are inserted after the integrator-fee params and before skipNonce, keeping apiKeyIndex/accountIndex last (WASM getClient reads them from the tail). WASM arg-count checks and "expects N args" messages bumped accordingly.

Example call sites (required to keep CI green)

CI compiles and runs the C++/Java/Rust/WASM examples, which call these exported functions, so their call sites were mechanically updated to pass the new defaults (0/0/255) — no logic changes. This is the only reason the PR touches examples/.

Verification

  • go build -buildmode=c-shared (sharedlib) + generated header signatures confirmed
  • go build GOOS=js GOARCH=wasm (wasm) + node examples/wasm/test_wasm.mjs → all assertions pass
  • cargo build --release (rust example) + g++ compile of cpp example
  • gofmt, go vet, go test ./... clean
  • (Java/mvn not available locally; JNA interface updated to match the generated header)

Link to Devin session: https://app.devin.ai/sessions/08b2387465664e789286a14d3078a1a4
Requested by: @mihaimarcu2004


Open in Devin Review

Co-Authored-By: mihai <mihai2004marcu@gmail.com>
@devin-ai-integration
Copy link
Copy Markdown
Contributor

🤖 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 that start with 'DevinAI' or '@devin'.
  • 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, CI, and merge conflict monitoring

@devin-ai-integration devin-ai-integration Bot deleted the devin/1780493092-wire-self-trade-sharedlib-wasm branch June 3, 2026 13:36
Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration Bot left a comment

Choose a reason for hiding this comment

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

Devin Review found 1 potential issue.

View 5 additional findings in Devin Review.

Open in Devin Review

Comment thread sharedlib/main.go
Comment on lines 129 to +138
if skipNonce == 1 {
attr.SkipNonce = &skipNonce
}
if selfTradeBehaviorMode != txtypes.SelfTradeBehaviorExpireMaker {
attr.SelfTradeBehaviorMode = &selfTradeBehaviorMode
}
if selfTradeEqualityMode != txtypes.SelfTradeEqualityAccountIndex {
attr.SelfTradeEqualityMode = &selfTradeEqualityMode
}
return &attr
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔴 Self-trade attributes unusable due to nil-valued integrator entries exceeding NbAttributesPerTx limit

Both CreateIntegratorTxAttributes (sharedlib) and integratorTxAttributes (wasm) unconditionally set IntegratorAccountIndex, IntegratorTakerFee, and IntegratorMakerFee pointers — even when their values are 0 (the nil value). ConstructL2TxAttributes (types/tx_request.go:193-201) then adds these to the L2TxAttributes map since the pointers are non-nil. The Validate() method at types/txtypes/tx_attributes.go:129 checks len(attr) > NbAttributesPerTx where NbAttributesPerTx=4 (types/txtypes/constants.go:198), counting ALL entries including nil-valued ones.

This means using any non-default self-trade mode with skipNonce produces 5 entries (3 nil-valued integrator + 1 selfTrade + 1 skipNonce) → ErrTooManyAttributes. Using BOTH non-default self-trade modes produces 5 entries even without skipNonce (3 nil-valued integrator + 2 selfTrade) → also fails. The feature is effectively broken for these common use cases.

Example failing scenario trace

Calling SignCreateOrder with integratorAccountIndex=0, integratorTakerFee=0, integratorMakerFee=0, selfTradeBehaviorMode=1, selfTradeEqualityMode=0, skipNonce=1:

  1. CreateIntegratorTxAttributes sets: IntegratorAccountIndex=&0, IntegratorTakerFee=&0, IntegratorMakerFee=&0, SkipNonce=&1, SelfTradeBehaviorMode=&1
  2. ConstructL2TxAttributes adds 5 map entries (all pointers non-nil)
  3. Validate() sees len(attr)=5 > 4 → returns ErrTooManyAttributes

The nil-valued integrator entries don't affect the hash (skipped in getNormalizedTypes) and IsEmpty() considers them empty, but they still count toward the 4-attribute limit.

(Refers to lines 124-138)

Prompt for agents
The CreateIntegratorTxAttributes function in sharedlib/main.go (and the equivalent integratorTxAttributes in wasm/main.go) unconditionally sets IntegratorAccountIndex, IntegratorTakerFee, and IntegratorMakerFee pointers even when their values equal the nil sentinel values (all 0). This wastes attribute slots in the L2TxAttributes map, which has a hard limit of NbAttributesPerTx=4 entries.

The fix is to only set these pointers when the values differ from the nil values. Both functions need the same change:

1. sharedlib/main.go CreateIntegratorTxAttributes (around line 124-138): Instead of unconditionally setting attr.IntegratorAccountIndex, attr.IntegratorTakerFee, and attr.IntegratorMakerFee, guard each with a nil-value check, similar to the self-trade and skipNonce fields. The nil values are: NilIntegratorIndex=0 (txtypes constant), NilIntegratorTakerFee=0, NilIntegratorMakerFee=0.

2. wasm/main.go integratorTxAttributes (around line 38-53): Same change — guard the integrator fields with nil-value checks instead of unconditionally including them in the struct initializer.

This is safe because absent entries and nil-valued entries behave identically: GetValueOrDefault returns the nil value for missing keys, and getNormalizedTypes and IsEmpty both skip nil-valued entries.
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Confirmed and fixed. Reproduced exactly as described: CreateIntegratorTxAttributes (sharedlib) / integratorTxAttributes (wasm) set the 3 integrator pointers unconditionally, so an order with integrator values 0 + a non-default self-trade mode + skipNonce produced 5 map entries ({1:0, 2:0, 3:0, 4:1, 6:1}) → ErrTooManyAttributes (limit NbAttributesPerTx=4).

Fix: only set the integrator pointers when the value differs from its nil sentinel (NilIntegratorIndex/NilIntegratorTakerFee/NilIntegratorMakerFee, all 0), matching how skipNonce and the self-trade modes are already handled.

This is signature-preserving: getNormalizedTypes() already skips nil-valued entries, so the attribute Hash() is byte-identical with or without the 0-valued integrator keys. Verified with a unit check — old map (with nil integrator entries) fails Validate(), new map passes, and old.Hash() == new.Hash(). WASM SignCreateOrder now emits L2TxAttributes":{"4":1} instead of {"1":0,"2":0,"3":0,"4":1}.

Note: PR #76 was closed at the requester's instruction — the fix landed directly on self-trade as commit 3718eab (alongside the original d09f1e0).

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.

1 participant