Skip to content

Commit 8a43ec0

Browse files
tx attributes & integrator fees (#54)
* update txtypes * add req and get for L2ApproveIntegrator * add L1Sig capabilities for ApproveIntegrator, add SignApproveIntegrator to sharedlib * Pass integrator attributes to create order tx * Pass integrator attributes to modify order tx * wasm + readme --------- Co-authored-by: mihaimarcu <mihai2004marcu@gmail.com>
1 parent db5e4ec commit 8a43ec0

17 files changed

Lines changed: 740 additions & 173 deletions

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@ SignBurnShares
5353
=== Staking ===
5454
SignStakeAssets
5555
SignUnstakeAssets
56+
57+
=== Integrators ===
58+
SignApproveIntegrator
5659
```
5760

5861
## How to specify an account

client/client.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ var (
2222

2323
// GenerateAPIKey generates a new API key pair from a seed
2424
func GenerateAPIKey() (string, string, error) {
25-
key := curve.SampleScalar(nil)
25+
key := curve.SampleScalar()
2626
publicKeyStr := hexutil.Encode(schnorr.SchnorrPkFromSk(key).ToLittleEndianBytes())
2727
privateKeyStr := hexutil.Encode(key.ToLittleEndianBytes())
2828

client/tx_get.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,3 +231,23 @@ func (c *TxClient) GetUnstakeAssetsTransaction(tx *types.UnstakeAssetsTxReq, ops
231231
}
232232
return txInfo, nil
233233
}
234+
235+
func (c *TxClient) GetApproveIntegratorTx(tx *types.ApproveIntegratorTxReq, ops *types.TransactOpts) (*txtypes.L2ApproveIntegratorTxInfo, error) {
236+
ops, err := c.FullFillDefaultOps(ops)
237+
if err != nil {
238+
return nil, err
239+
}
240+
txInfo, err := types.ConstructApproveIntegratorTx(c.keyManager, c.chainId, tx, ops)
241+
if err != nil {
242+
return nil, err
243+
}
244+
245+
pk := c.keyManager.PubKeyBytes()
246+
msgHash, _ := txInfo.Hash(c.chainId)
247+
248+
if err := schnorr.Validate(pk[:], msgHash, txInfo.Sig); err != nil {
249+
return nil, fmt.Errorf("failed to validate signature. error: %v", err)
250+
}
251+
252+
return txInfo, nil
253+
}

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ go 1.23.0
55
toolchain go1.23.1
66

77
require (
8-
github.com/elliottech/poseidon_crypto v0.0.11
8+
github.com/elliottech/poseidon_crypto v0.0.15
99
github.com/ethereum/go-ethereum v1.15.6
1010
)
1111

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK
2020
github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc=
2121
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 h1:YLtO71vCjJRCBcrPMtQ9nqBsqpA1m5sE92cU+pd5Mcc=
2222
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs=
23-
github.com/elliottech/poseidon_crypto v0.0.11 h1:iX4rCg0m1XIX/7mhXVUEYUJIdQD57zNGNLeb6RZRl7g=
24-
github.com/elliottech/poseidon_crypto v0.0.11/go.mod h1:NhWxSjPGr5JXRuB2Aepl/+ZrbmUG3hvku/GarB1JR8c=
23+
github.com/elliottech/poseidon_crypto v0.0.15 h1:+f/YTnIFEWX1Xss75Ky7QRvhDpR372XAAMtpWxKvp+k=
24+
github.com/elliottech/poseidon_crypto v0.0.15/go.mod h1:/nFxH8V+3yk3eakI+Arlu5U8XwRXgydBvsiwfA/yYrg=
2525
github.com/ethereum/c-kzg-4844 v1.0.0 h1:0X1LBXxaEtYD9xsyj9B9ctQEZIpnvVDeoBx8aHEwTNA=
2626
github.com/ethereum/c-kzg-4844 v1.0.0/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0=
2727
github.com/ethereum/go-ethereum v1.15.6 h1:jgLoUM6/pNjp0uEnXyWcWikDwa4j1wZlcqkX8Pm8A+I=

sharedlib/main.go

Lines changed: 82 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ typedef struct {
3636
} ApiKeyResponse;
3737
3838
typedef struct {
39-
uint8_t MarketIndex;
39+
int16_t MarketIndex;
4040
int64_t ClientOrderIndex;
4141
int64_t BaseAmount;
4242
uint32_t Price;
@@ -46,6 +46,9 @@ typedef struct {
4646
uint8_t ReduceOnly;
4747
uint32_t TriggerPrice;
4848
int64_t OrderExpiry;
49+
int64_t IntegratorAccountIndex;
50+
int64_t IntegratorMakerFee;
51+
int64_t IntegratorTakerFee;
4952
} CreateOrderTxReq;
5053
*/
5154
import "C"
@@ -65,6 +68,8 @@ func messageToSign(txInfo txtypes.TxInfo) string {
6568
return typed.GetL1SignatureBody()
6669
case *txtypes.L2TransferTxInfo:
6770
return typed.GetL1SignatureBody(chainId)
71+
case *txtypes.L2ApproveIntegratorTxInfo:
72+
return typed.GetL1SignatureBody(chainId)
6873
default:
6974
return ""
7075
}
@@ -207,7 +212,7 @@ func SignChangePubKey(cPubKey *C.char, cNonce C.longlong, cApiKeyIndex C.int, cA
207212
}
208213

209214
//export SignCreateOrder
210-
func SignCreateOrder(cMarketIndex C.int, cClientOrderIndex C.longlong, cBaseAmount C.longlong, cPrice C.int, cIsAsk C.int, cOrderType C.int, cTimeInForce C.int, cReduceOnly C.int, cTriggerPrice C.int, cOrderExpiry C.longlong, cNonce C.longlong, cApiKeyIndex C.int, cAccountIndex C.longlong) (ret C.SignedTxResponse) {
215+
func SignCreateOrder(cMarketIndex C.int, cClientOrderIndex C.longlong, cBaseAmount C.longlong, cPrice C.int, cIsAsk C.int, cOrderType C.int, cTimeInForce C.int, cReduceOnly C.int, cTriggerPrice C.int, cOrderExpiry C.longlong, cIntegratorAccountIndex C.int, cIntegratorTakerFee C.int, cIntegratorMakerFee C.int, cNonce C.longlong, cApiKeyIndex C.int, cAccountIndex C.longlong) (ret C.SignedTxResponse) {
211216
defer func() {
212217
if r := recover(); r != nil {
213218
ret = signedTxResponsePanic(r)
@@ -230,21 +235,28 @@ func SignCreateOrder(cMarketIndex C.int, cClientOrderIndex C.longlong, cBaseAmou
230235
triggerPrice := uint32(cTriggerPrice)
231236
orderExpiry := int64(cOrderExpiry)
232237

238+
integratorAccountIndex := int(cIntegratorAccountIndex)
239+
integratorMakerFee := int(cIntegratorMakerFee)
240+
integratorTakerFee := int(cIntegratorTakerFee)
241+
233242
if orderExpiry == -1 {
234243
orderExpiry = time.Now().Add(time.Hour * 24 * 28).UnixMilli() // 28 days
235244
}
236245

237246
tx := &types.CreateOrderTxReq{
238-
MarketIndex: marketIndex,
239-
ClientOrderIndex: clientOrderIndex,
240-
BaseAmount: baseAmount,
241-
Price: price,
242-
IsAsk: isAsk,
243-
Type: orderType,
244-
TimeInForce: timeInForce,
245-
ReduceOnly: reduceOnly,
246-
TriggerPrice: triggerPrice,
247-
OrderExpiry: orderExpiry,
247+
MarketIndex: marketIndex,
248+
ClientOrderIndex: clientOrderIndex,
249+
BaseAmount: baseAmount,
250+
Price: price,
251+
IsAsk: isAsk,
252+
Type: orderType,
253+
TimeInForce: timeInForce,
254+
ReduceOnly: reduceOnly,
255+
TriggerPrice: triggerPrice,
256+
OrderExpiry: orderExpiry,
257+
IntegratorAccountIndex: integratorAccountIndex,
258+
IntegratorTakerFee: integratorTakerFee,
259+
IntegratorMakerFee: integratorMakerFee,
248260
}
249261
ops := getTransactOpts(cNonce)
250262

@@ -278,16 +290,19 @@ func SignCreateGroupedOrders(cGroupingType C.uint8_t, cOrders *C.CreateOrderTxRe
278290
}
279291

280292
orders[i] = &types.CreateOrderTxReq{
281-
MarketIndex: int16(order.MarketIndex),
282-
ClientOrderIndex: int64(order.ClientOrderIndex),
283-
BaseAmount: int64(order.BaseAmount),
284-
Price: uint32(order.Price),
285-
IsAsk: uint8(order.IsAsk),
286-
Type: uint8(order.Type),
287-
TimeInForce: uint8(order.TimeInForce),
288-
ReduceOnly: uint8(order.ReduceOnly),
289-
TriggerPrice: uint32(order.TriggerPrice),
290-
OrderExpiry: orderExpiry,
293+
MarketIndex: int16(order.MarketIndex),
294+
ClientOrderIndex: int64(order.ClientOrderIndex),
295+
BaseAmount: int64(order.BaseAmount),
296+
Price: uint32(order.Price),
297+
IsAsk: uint8(order.IsAsk),
298+
Type: uint8(order.Type),
299+
TimeInForce: uint8(order.TimeInForce),
300+
ReduceOnly: uint8(order.ReduceOnly),
301+
TriggerPrice: uint32(order.TriggerPrice),
302+
OrderExpiry: orderExpiry,
303+
IntegratorAccountIndex: int(order.IntegratorAccountIndex),
304+
IntegratorTakerFee: int(order.IntegratorTakerFee),
305+
IntegratorMakerFee: int(order.IntegratorMakerFee),
291306
}
292307
}
293308

@@ -401,7 +416,7 @@ func SignCancelAllOrders(cTimeInForce C.int, cTime C.longlong, cNonce C.longlong
401416
}
402417

403418
//export SignModifyOrder
404-
func SignModifyOrder(cMarketIndex C.int, cIndex C.longlong, cBaseAmount C.longlong, cPrice C.longlong, cTriggerPrice C.longlong, cNonce C.longlong, cApiKeyIndex C.int, cAccountIndex C.longlong) (ret C.SignedTxResponse) {
419+
func SignModifyOrder(cMarketIndex C.int, cIndex C.longlong, cBaseAmount C.longlong, cPrice C.longlong, cTriggerPrice C.longlong, cIntegratorAccountIndex C.int, cIntegratorTakerFee C.int, cIntegratorMakerFee C.int, cNonce C.longlong, cApiKeyIndex C.int, cAccountIndex C.longlong) (ret C.SignedTxResponse) {
405420
defer func() {
406421
if r := recover(); r != nil {
407422
ret = signedTxResponsePanic(r)
@@ -419,12 +434,19 @@ func SignModifyOrder(cMarketIndex C.int, cIndex C.longlong, cBaseAmount C.longlo
419434
price := uint32(cPrice)
420435
triggerPrice := uint32(cTriggerPrice)
421436

437+
integratorAccountIndex := int(cIntegratorAccountIndex)
438+
integratorMakerFee := int(cIntegratorMakerFee)
439+
integratorTakerFee := int(cIntegratorTakerFee)
440+
422441
tx := &types.ModifyOrderTxReq{
423-
MarketIndex: marketIndex,
424-
Index: index,
425-
BaseAmount: baseAmount,
426-
Price: price,
427-
TriggerPrice: triggerPrice,
442+
MarketIndex: marketIndex,
443+
Index: index,
444+
BaseAmount: baseAmount,
445+
Price: price,
446+
TriggerPrice: triggerPrice,
447+
IntegratorAccountIndex: integratorAccountIndex,
448+
IntegratorTakerFee: integratorTakerFee,
449+
IntegratorMakerFee: integratorMakerFee,
428450
}
429451
ops := getTransactOpts(cNonce)
430452

@@ -738,4 +760,36 @@ func SignUnstakeAssets(cStakingPoolIndex C.longlong, cShareAmount C.longlong, cN
738760
return convertTxInfoToResponse(txInfo, err)
739761
}
740762

763+
//export SignApproveIntegrator
764+
func SignApproveIntegrator(cIntegratorIndex C.longlong, cMaxPerpsTakerFee C.uint32_t, cMaxPerpsMakerFee C.uint32_t, cMaxSpotTakerFee C.uint32_t, cMaxSpotMakerFee C.uint32_t, cApprovalExpiry C.longlong, cNonce C.longlong, cApiKeyIndex C.int, cAccountIndex C.longlong) (ret C.SignedTxResponse) {
765+
defer func() {
766+
if r := recover(); r != nil {
767+
ret = signedTxResponsePanic(r)
768+
}
769+
}()
770+
c, err := getClient(cApiKeyIndex, cAccountIndex)
771+
if err != nil {
772+
return signedTxResponseErr(err)
773+
}
774+
775+
IntegratorIndex := int64(cIntegratorIndex)
776+
MaxPerpsMakerFee := uint32(cMaxPerpsMakerFee)
777+
MaxPerpsTakerFee := uint32(cMaxPerpsTakerFee)
778+
MaxSpotMakerFee := uint32(cMaxSpotMakerFee)
779+
MaxSpotTakerFee := uint32(cMaxSpotTakerFee)
780+
ApprovalExpiry := int64(cApprovalExpiry)
781+
782+
tx := &types.ApproveIntegratorTxReq{
783+
IntegratorAccountIndex: IntegratorIndex,
784+
MaxPerpsTakerFee: MaxPerpsTakerFee,
785+
MaxPerpsMakerFee: MaxPerpsMakerFee,
786+
MaxSpotTakerFee: MaxSpotTakerFee,
787+
MaxSpotMakerFee: MaxSpotMakerFee,
788+
ApprovalExpiry: ApprovalExpiry,
789+
}
790+
ops := getTransactOpts(cNonce)
791+
txInfo, err := c.GetApproveIntegratorTx(tx, ops)
792+
return convertTxInfoToResponse(txInfo, err)
793+
}
794+
741795
func main() {}

types/tx_request.go

Lines changed: 79 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -43,16 +43,19 @@ type WithdrawTxReq struct {
4343
}
4444

4545
type CreateOrderTxReq struct {
46-
MarketIndex int16
47-
ClientOrderIndex int64
48-
BaseAmount int64
49-
Price uint32
50-
IsAsk uint8
51-
Type uint8
52-
TimeInForce uint8
53-
ReduceOnly uint8
54-
TriggerPrice uint32
55-
OrderExpiry int64
46+
MarketIndex int16
47+
ClientOrderIndex int64
48+
BaseAmount int64
49+
Price uint32
50+
IsAsk uint8
51+
Type uint8
52+
TimeInForce uint8
53+
ReduceOnly uint8
54+
TriggerPrice uint32
55+
OrderExpiry int64
56+
IntegratorAccountIndex int
57+
IntegratorMakerFee int
58+
IntegratorTakerFee int
5659
}
5760

5861
type CreateGroupedOrdersTxReq struct {
@@ -61,11 +64,14 @@ type CreateGroupedOrdersTxReq struct {
6164
}
6265

6366
type ModifyOrderTxReq struct {
64-
MarketIndex int16
65-
Index int64
66-
BaseAmount int64
67-
Price uint32
68-
TriggerPrice uint32
67+
MarketIndex int16
68+
Index int64
69+
BaseAmount int64
70+
Price uint32
71+
TriggerPrice uint32
72+
IntegratorAccountIndex int
73+
IntegratorMakerFee int
74+
IntegratorTakerFee int
6975
}
7076

7177
type CancelOrderTxReq struct {
@@ -123,6 +129,15 @@ type UpdateMarginTxReq struct {
123129
Direction uint8
124130
}
125131

132+
type ApproveIntegratorTxReq struct {
133+
IntegratorAccountIndex int64
134+
MaxPerpsTakerFee uint32
135+
MaxPerpsMakerFee uint32
136+
MaxSpotTakerFee uint32
137+
MaxSpotMakerFee uint32
138+
ApprovalExpiry int64
139+
}
140+
126141
func ConstructAuthToken(key signer.Signer, deadline time.Time, ops *TransactOpts) (string, error) {
127142
if ops.FromAccountIndex == nil {
128143
return "", fmt.Errorf("missing FromAccountIndex")
@@ -478,6 +493,28 @@ func ConstructUpdateMarginTx(key signer.Signer, lighterChainId uint32, tx *Updat
478493
return convertedTx, nil
479494
}
480495

496+
func ConstructApproveIntegratorTx(key signer.Signer, lighterChainId uint32, tx *ApproveIntegratorTxReq, ops *TransactOpts) (*txtypes.L2ApproveIntegratorTxInfo, error) {
497+
convertedTx := ConvertApproveIntegratorTx(tx, ops)
498+
err := convertedTx.Validate()
499+
if err != nil {
500+
return nil, err
501+
}
502+
503+
msgHash, err := convertedTx.Hash(lighterChainId)
504+
if err != nil {
505+
return nil, err
506+
}
507+
508+
signature, err := key.Sign(msgHash, p2.NewPoseidon2())
509+
if err != nil {
510+
return nil, err
511+
}
512+
513+
convertedTx.SignedHash = ethCommon.Bytes2Hex(msgHash)
514+
convertedTx.Sig = signature
515+
return convertedTx, nil
516+
}
517+
481518
func ConvertTransferTx(tx *TransferTxReq, ops *TransactOpts) *txtypes.L2TransferTxInfo {
482519
return &txtypes.L2TransferTxInfo{
483520
FromAccountIndex: *ops.FromAccountIndex,
@@ -511,6 +548,11 @@ func ConvertCreateOrderTx(tx *CreateOrderTxReq, ops *TransactOpts) *txtypes.L2Cr
511548
},
512549
ExpiredAt: ops.ExpiredAt,
513550
Nonce: *ops.Nonce,
551+
L2TxAttributes: txtypes.L2TxAttributes{
552+
txtypes.AttributeTypeIntegratorAccountIndex: tx.IntegratorAccountIndex,
553+
txtypes.AttributeTypeIntegratorTakerFee: tx.IntegratorTakerFee,
554+
txtypes.AttributeTypeIntegratorMakerFee: tx.IntegratorMakerFee,
555+
},
514556
}
515557
}
516558

@@ -563,6 +605,11 @@ func ConvertModifyOrderTx(tx *ModifyOrderTxReq, ops *TransactOpts) *txtypes.L2Mo
563605
TriggerPrice: tx.TriggerPrice,
564606
ExpiredAt: ops.ExpiredAt,
565607
Nonce: *ops.Nonce,
608+
L2TxAttributes: txtypes.L2TxAttributes{
609+
txtypes.AttributeTypeIntegratorAccountIndex: tx.IntegratorAccountIndex,
610+
txtypes.AttributeTypeIntegratorTakerFee: tx.IntegratorTakerFee,
611+
txtypes.AttributeTypeIntegratorMakerFee: tx.IntegratorMakerFee,
612+
},
566613
}
567614
}
568615

@@ -744,3 +791,20 @@ func ConvertUnstakeAssetsTx(tx *UnstakeAssetsTxReq, ops *TransactOpts) *txtypes.
744791
Nonce: *ops.Nonce,
745792
}
746793
}
794+
795+
func ConvertApproveIntegratorTx(tx *ApproveIntegratorTxReq, ops *TransactOpts) *txtypes.L2ApproveIntegratorTxInfo {
796+
return &txtypes.L2ApproveIntegratorTxInfo{
797+
AccountIndex: *ops.FromAccountIndex,
798+
ApiKeyIndex: *ops.ApiKeyIndex,
799+
800+
IntegratorAccountIndex: tx.IntegratorAccountIndex,
801+
MaxPerpsTakerFee: tx.MaxPerpsTakerFee,
802+
MaxPerpsMakerFee: tx.MaxPerpsMakerFee,
803+
MaxSpotTakerFee: tx.MaxSpotTakerFee,
804+
MaxSpotMakerFee: tx.MaxSpotMakerFee,
805+
ApprovalExpiry: tx.ApprovalExpiry,
806+
807+
ExpiredAt: ops.ExpiredAt,
808+
Nonce: *ops.Nonce,
809+
}
810+
}

0 commit comments

Comments
 (0)