mirror of
https://github.com/discountry/ritmex-bot.git
synced 2026-09-11 17:28:08 +00:00
Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5f79b134f2 | ||
|
|
85705dd27c |
@@ -114,16 +114,3 @@ PARADEX_WALLET_ADDRESS=
|
||||
|
||||
# Enable verbose adapter logging: set to "1" or "true"
|
||||
# PARADEX_DEBUG=false
|
||||
|
||||
# Extended exchange configuration (Starknet)
|
||||
# Set EXCHANGE=extended to activate. Requires on-chain Stark key + vault id.
|
||||
EXTENDED_API_KEY=
|
||||
EXTENDED_STARK_PRIVATE_KEY= # 0x-prefixed Stark private key for signing orders
|
||||
EXTENDED_VAULT_ID= # Vault/sub-account id from Extended UI
|
||||
EXTENDED_MARKET=BTC-USD # Defaults to TRADE_SYMBOL when omitted
|
||||
|
||||
# Optional overrides (defaults target mainnet host)
|
||||
# EXTENDED_API_HOST=api.starknet.extended.exchange
|
||||
# EXTENDED_STREAM_HOST=api.starknet.extended.exchange
|
||||
# EXTENDED_PRIVATE_STREAM_HOST=api.starknet.extended.exchange
|
||||
# EXTENDED_USER_AGENT=ritmex-bot
|
||||
|
||||
@@ -4,7 +4,8 @@
|
||||
|
||||
如果您希望获取优惠并支持本项目,请考虑使用以下注册链接:
|
||||
|
||||
* [Aster 30% 手续费优惠注册链接](https://www.asterdex.com/zh-CN/referral/4665f3)
|
||||
* [Lighter 手续费优惠注册链接](https://app.lighter.xyz/?referral=111909FA)
|
||||
* [Aster 手续费优惠注册链接](https://www.asterdex.com/zh-CN/referral/4665f3)
|
||||
* [Binance 手续费优惠注册链接](https://www.binance.com/join?ref=KNKCA9XC)
|
||||
* [GRVT 手续费优惠注册链接](https://grvt.io/exchange/sign-up?ref=sea)
|
||||
* [Backpack 手续费优惠注册链接](https://backpack.exchange/join/ritmex)
|
||||
|
||||
+2
-1
@@ -2,7 +2,8 @@
|
||||
|
||||
A Bun-powered multi-exchange perpetuals workstation that ships an SMA30 trend engine, a Guardian stop sentinel, and two market-making modes. It offers instant restarts, realtime market data, structured logging, and an Ink-based CLI dashboard.
|
||||
|
||||
* [Aster referral (30% fee discount)](https://www.asterdex.com/en/referral/4665f3)
|
||||
* [Lighter referral link](https://app.lighter.xyz/?referral=111909FA)
|
||||
* [Aster referral link](https://www.asterdex.com/en/referral/4665f3)
|
||||
* [Binance referral link](https://www.binance.com/join?ref=KNKCA9XC)
|
||||
* [GRVT referral link](https://grvt.io/exchange/sign-up?ref=sea)
|
||||
* [Backpack referral link](https://backpack.exchange/join/ritmex)
|
||||
|
||||
@@ -6,16 +6,12 @@
|
||||
"dependencies": {
|
||||
"@grvt/client": "^1.6.4",
|
||||
"@noble/ed25519": "^3.0.0",
|
||||
"@x10xchange/stark-crypto-wrapper-wasm": "^0.2.0",
|
||||
"axios": "^1.12.2",
|
||||
"bignumber.js": "^9.3.1",
|
||||
"ccxt": "^4.5.12",
|
||||
"date-fns": "^4.1.0",
|
||||
"dotenv": "^17.2.2",
|
||||
"ethereum-cryptography": "^2.1.3",
|
||||
"ink": "^6.3.1",
|
||||
"react": "^19.1.1",
|
||||
"starknet": "^8.5.4",
|
||||
"ws": "^8.18.3",
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -136,18 +132,12 @@
|
||||
|
||||
"@rollup/rollup-win32-x64-msvc": ["@rollup/rollup-win32-x64-msvc@4.52.0", "", { "os": "win32", "cpu": "x64" }, "sha512-6iKDCVSIUQ8jPMoIV0OytRKniaYyy5EbY/RRydmLW8ZR3cEBhxbWl5ro0rkUNe0ef6sScvhbY79HrjRm8i3vDQ=="],
|
||||
|
||||
"@scure/base": ["@scure/base@1.2.6", "", {}, "sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg=="],
|
||||
"@scure/base": ["@scure/base@1.1.9", "", {}, "sha512-8YKhl8GHiNI/pU2VMaofa2Tor7PJRAjwQLBBuilkJ9L5+13yVbC7JO/wS7piioAvPSwR3JKM1IJ/u4xQzbcXKg=="],
|
||||
|
||||
"@scure/bip32": ["@scure/bip32@1.4.0", "", { "dependencies": { "@noble/curves": "~1.4.0", "@noble/hashes": "~1.4.0", "@scure/base": "~1.1.6" } }, "sha512-sVUpc0Vq3tXCkDGYVWGIZTRfnvu8LoTDaev7vbwh0omSvVORONr960MQWdKqJDCReIEmTj3PAr73O3aoxz7OPg=="],
|
||||
|
||||
"@scure/bip39": ["@scure/bip39@1.3.0", "", { "dependencies": { "@noble/hashes": "~1.4.0", "@scure/base": "~1.1.6" } }, "sha512-disdg7gHuTDZtY+ZdkmLpPCk7fxZSu3gBiEGuoC1XYxv9cGx3Z6cpTggCgW6odSOOIXCiDjuGejW+aJKCY/pIQ=="],
|
||||
|
||||
"@scure/starknet": ["@scure/starknet@1.1.0", "", { "dependencies": { "@noble/curves": "~1.7.0", "@noble/hashes": "~1.6.0" } }, "sha512-83g3M6Ix2qRsPN4wqLDqiRZ2GBNbjVWfboJE/9UjfG+MHr6oDSu/CWgy8hsBSJejr09DkkL+l0Ze4KVrlCIdtQ=="],
|
||||
|
||||
"@starknet-io/starknet-types-08": ["@starknet-io/types-js@0.8.4", "", {}, "sha512-0RZ3TZHcLsUTQaq1JhDSCM8chnzO4/XNsSCozwDET64JK5bjFDIf2ZUkta+tl5Nlbf4usoU7uZiDI/Q57kt2SQ=="],
|
||||
|
||||
"@starknet-io/starknet-types-09": ["@starknet-io/types-js@0.9.2", "", {}, "sha512-vWOc0FVSn+RmabozIEWcEny1I73nDGTvOrLYJsR1x7LGA3AZmqt4i/aW69o/3i2NN5CVP8Ok6G1ayRQJKye3Wg=="],
|
||||
|
||||
"@types/bun": ["@types/bun@1.2.22", "", { "dependencies": { "bun-types": "1.2.22" } }, "sha512-5A/KrKos2ZcN0c6ljRSOa1fYIyCKhZfIVYeuyb4snnvomnpFqC0tTsEkdqNxbAgExV384OETQ//WAjl3XbYqQA=="],
|
||||
|
||||
"@types/chai": ["@types/chai@5.2.2", "", { "dependencies": { "@types/deep-eql": "*" } }, "sha512-8kB30R7Hwqf40JPiKhVzodJs2Qc1ZJ5zuT3uzw5Hq/dhNCl3G3l83jfpdI1e20BP348+fV7VIL/+FxaXkqBmWg=="],
|
||||
@@ -178,18 +168,12 @@
|
||||
|
||||
"@vitest/utils": ["@vitest/utils@3.2.4", "", { "dependencies": { "@vitest/pretty-format": "3.2.4", "loupe": "^3.1.4", "tinyrainbow": "^2.0.0" } }, "sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA=="],
|
||||
|
||||
"@x10xchange/stark-crypto-wrapper-wasm": ["@x10xchange/stark-crypto-wrapper-wasm@0.2.0", "", {}, "sha512-pi7cHvDgPf9Ri9q0cvrUnCnucafB+F3ch7ia0oEJhKMY+bWvxWRYA2vve9s6UMMNV6PnmTyFZPOYptVGGdLTWA=="],
|
||||
|
||||
"abi-wan-kanabi": ["abi-wan-kanabi@2.2.4", "", { "dependencies": { "ansicolors": "^0.3.2", "cardinal": "^2.1.1", "fs-extra": "^10.0.0", "yargs": "^17.7.2" }, "bin": { "generate": "dist/generate.js" } }, "sha512-0aA81FScmJCPX+8UvkXLki3X1+yPQuWxEkqXBVKltgPAK79J+NB+Lp5DouMXa7L6f+zcRlIA/6XO7BN/q9fnvg=="],
|
||||
|
||||
"ansi-escapes": ["ansi-escapes@7.1.0", "", { "dependencies": { "environment": "^1.0.0" } }, "sha512-YdhtCd19sKRKfAAUsrcC1wzm4JuzJoiX4pOJqIoW2qmKj5WzG/dL8uUJ0361zaXtHqK7gEhOwtAtz7t3Yq3X5g=="],
|
||||
|
||||
"ansi-regex": ["ansi-regex@6.2.2", "", {}, "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg=="],
|
||||
|
||||
"ansi-styles": ["ansi-styles@6.2.3", "", {}, "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg=="],
|
||||
|
||||
"ansicolors": ["ansicolors@0.3.2", "", {}, "sha512-QXu7BPrP29VllRxH8GwB7x5iX5qWKAAMLqKQGWTeLWVlNHNOpVMJ91dsxQAIWXpjuW5wqvxu3Jd/nRjrJ+0pqg=="],
|
||||
|
||||
"assertion-error": ["assertion-error@2.0.1", "", {}, "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA=="],
|
||||
|
||||
"asynckit": ["asynckit@0.4.0", "", {}, "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="],
|
||||
@@ -198,16 +182,12 @@
|
||||
|
||||
"axios": ["axios@1.12.2", "", { "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.4", "proxy-from-env": "^1.1.0" } }, "sha512-vMJzPewAlRyOgxV2dU0Cuz2O8zzzx9VYtbJOaBgXFeLc4IV/Eg50n4LowmehOOR61S8ZMpc2K5Sa7g6A4jfkUw=="],
|
||||
|
||||
"bignumber.js": ["bignumber.js@9.3.1", "", {}, "sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ=="],
|
||||
|
||||
"bun-types": ["bun-types@1.2.22", "", { "dependencies": { "@types/node": "*" }, "peerDependencies": { "@types/react": "^19" } }, "sha512-hwaAu8tct/Zn6Zft4U9BsZcXkYomzpHJX28ofvx7k0Zz2HNz54n1n+tDgxoWFGB4PcFvJXJQloPhaV2eP3Q6EA=="],
|
||||
|
||||
"cac": ["cac@6.7.14", "", {}, "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ=="],
|
||||
|
||||
"call-bind-apply-helpers": ["call-bind-apply-helpers@1.0.2", "", { "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2" } }, "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ=="],
|
||||
|
||||
"cardinal": ["cardinal@2.1.1", "", { "dependencies": { "ansicolors": "~0.3.2", "redeyed": "~2.1.0" }, "bin": { "cdl": "./bin/cdl.js" } }, "sha512-JSr5eOgoEymtYHBjNWyjrMqet9Am2miJhlfKNdqLp6zoeAh0KN5dRAcxlecj5mAJrmQomgiOBj35xHLrFjqBpw=="],
|
||||
|
||||
"ccxt": ["ccxt@4.5.12", "", { "dependencies": { "ws": "^8.8.1" } }, "sha512-2lfL2TKjq4vBkQUQWJfDqFywhvYCZmk9r0SWC8GqA4AHZ6qozKVUJowxQTvdRsLX9jBwYSE0nc7JVurBrQ6SHg=="],
|
||||
|
||||
"chai": ["chai@5.3.3", "", { "dependencies": { "assertion-error": "^2.0.1", "check-error": "^2.1.1", "deep-eql": "^5.0.1", "loupe": "^3.1.0", "pathval": "^2.0.0" } }, "sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw=="],
|
||||
@@ -222,22 +202,14 @@
|
||||
|
||||
"cli-truncate": ["cli-truncate@4.0.0", "", { "dependencies": { "slice-ansi": "^5.0.0", "string-width": "^7.0.0" } }, "sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA=="],
|
||||
|
||||
"cliui": ["cliui@8.0.1", "", { "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", "wrap-ansi": "^7.0.0" } }, "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ=="],
|
||||
|
||||
"code-excerpt": ["code-excerpt@4.0.0", "", { "dependencies": { "convert-to-spaces": "^2.0.1" } }, "sha512-xxodCmBen3iy2i0WtAK8FlFNrRzjUqjRsMfho58xT/wvZU1YTM3fCnRjcy1gJPMepaRlgm/0e6w8SpWHpn3/cA=="],
|
||||
|
||||
"color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="],
|
||||
|
||||
"color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="],
|
||||
|
||||
"combined-stream": ["combined-stream@1.0.8", "", { "dependencies": { "delayed-stream": "~1.0.0" } }, "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg=="],
|
||||
|
||||
"convert-to-spaces": ["convert-to-spaces@2.0.1", "", {}, "sha512-rcQ1bsQO9799wq24uE5AM2tAILy4gXGIK/njFWcVQkGNZ96edlpY+A7bjwvzjYvLDyzmG1MmMLZhpcsb+klNMQ=="],
|
||||
|
||||
"csstype": ["csstype@3.1.3", "", {}, "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="],
|
||||
|
||||
"date-fns": ["date-fns@4.1.0", "", {}, "sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg=="],
|
||||
|
||||
"debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="],
|
||||
|
||||
"deep-eql": ["deep-eql@5.0.2", "", {}, "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q=="],
|
||||
@@ -266,12 +238,8 @@
|
||||
|
||||
"esbuild": ["esbuild@0.25.10", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.10", "@esbuild/android-arm": "0.25.10", "@esbuild/android-arm64": "0.25.10", "@esbuild/android-x64": "0.25.10", "@esbuild/darwin-arm64": "0.25.10", "@esbuild/darwin-x64": "0.25.10", "@esbuild/freebsd-arm64": "0.25.10", "@esbuild/freebsd-x64": "0.25.10", "@esbuild/linux-arm": "0.25.10", "@esbuild/linux-arm64": "0.25.10", "@esbuild/linux-ia32": "0.25.10", "@esbuild/linux-loong64": "0.25.10", "@esbuild/linux-mips64el": "0.25.10", "@esbuild/linux-ppc64": "0.25.10", "@esbuild/linux-riscv64": "0.25.10", "@esbuild/linux-s390x": "0.25.10", "@esbuild/linux-x64": "0.25.10", "@esbuild/netbsd-arm64": "0.25.10", "@esbuild/netbsd-x64": "0.25.10", "@esbuild/openbsd-arm64": "0.25.10", "@esbuild/openbsd-x64": "0.25.10", "@esbuild/openharmony-arm64": "0.25.10", "@esbuild/sunos-x64": "0.25.10", "@esbuild/win32-arm64": "0.25.10", "@esbuild/win32-ia32": "0.25.10", "@esbuild/win32-x64": "0.25.10" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-9RiGKvCwaqxO2owP61uQ4BgNborAQskMR6QusfWzQqv7AZOg5oGehdY2pRJMTKuwxd1IDBP4rSbI5lHzU7SMsQ=="],
|
||||
|
||||
"escalade": ["escalade@3.2.0", "", {}, "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA=="],
|
||||
|
||||
"escape-string-regexp": ["escape-string-regexp@2.0.0", "", {}, "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w=="],
|
||||
|
||||
"esprima": ["esprima@4.0.1", "", { "bin": { "esparse": "./bin/esparse.js", "esvalidate": "./bin/esvalidate.js" } }, "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="],
|
||||
|
||||
"estree-walker": ["estree-walker@3.0.3", "", { "dependencies": { "@types/estree": "^1.0.0" } }, "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g=="],
|
||||
|
||||
"ethereum-cryptography": ["ethereum-cryptography@2.2.1", "", { "dependencies": { "@noble/curves": "1.4.2", "@noble/hashes": "1.4.0", "@scure/bip32": "1.4.0", "@scure/bip39": "1.3.0" } }, "sha512-r/W8lkHSiTLxUxW8Rf3u4HGB0xQweG2RyETjywylKZSzLWoWAijRz8WCuOtJ6wah+avllXBqZuk29HCCvhEIRg=="],
|
||||
@@ -284,14 +252,10 @@
|
||||
|
||||
"form-data": ["form-data@4.0.4", "", { "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", "es-set-tostringtag": "^2.1.0", "hasown": "^2.0.2", "mime-types": "^2.1.12" } }, "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow=="],
|
||||
|
||||
"fs-extra": ["fs-extra@10.1.0", "", { "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" } }, "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ=="],
|
||||
|
||||
"fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="],
|
||||
|
||||
"function-bind": ["function-bind@1.1.2", "", {}, "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="],
|
||||
|
||||
"get-caller-file": ["get-caller-file@2.0.5", "", {}, "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="],
|
||||
|
||||
"get-east-asian-width": ["get-east-asian-width@1.4.0", "", {}, "sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q=="],
|
||||
|
||||
"get-intrinsic": ["get-intrinsic@1.3.0", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.1.1", "function-bind": "^1.1.2", "get-proto": "^1.0.1", "gopd": "^1.2.0", "has-symbols": "^1.1.0", "hasown": "^2.0.2", "math-intrinsics": "^1.1.0" } }, "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ=="],
|
||||
@@ -300,8 +264,6 @@
|
||||
|
||||
"gopd": ["gopd@1.2.0", "", {}, "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg=="],
|
||||
|
||||
"graceful-fs": ["graceful-fs@4.2.11", "", {}, "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="],
|
||||
|
||||
"has-symbols": ["has-symbols@1.1.0", "", {}, "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ=="],
|
||||
|
||||
"has-tostringtag": ["has-tostringtag@1.0.2", "", { "dependencies": { "has-symbols": "^1.0.3" } }, "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw=="],
|
||||
@@ -318,10 +280,6 @@
|
||||
|
||||
"js-tokens": ["js-tokens@9.0.1", "", {}, "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ=="],
|
||||
|
||||
"jsonfile": ["jsonfile@6.2.0", "", { "dependencies": { "universalify": "^2.0.0" }, "optionalDependencies": { "graceful-fs": "^4.1.6" } }, "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg=="],
|
||||
|
||||
"lossless-json": ["lossless-json@4.3.0", "", {}, "sha512-ToxOC+SsduRmdSuoLZLYAr5zy1Qu7l5XhmPWM3zefCZ5IcrzW/h108qbJUKfOlDlhvhjUK84+8PSVX0kxnit0g=="],
|
||||
|
||||
"loupe": ["loupe@3.2.1", "", {}, "sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ=="],
|
||||
|
||||
"magic-string": ["magic-string@0.30.19", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw=="],
|
||||
@@ -340,8 +298,6 @@
|
||||
|
||||
"onetime": ["onetime@5.1.2", "", { "dependencies": { "mimic-fn": "^2.1.0" } }, "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg=="],
|
||||
|
||||
"pako": ["pako@2.1.0", "", {}, "sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug=="],
|
||||
|
||||
"patch-console": ["patch-console@2.0.0", "", {}, "sha512-0YNdUceMdaQwoKce1gatDScmMo5pu/tfABfnzEqeG0gtTmd7mh/WcwgUjtAeOU7N8nFFlbQBnFK2gXW5fGvmMA=="],
|
||||
|
||||
"pathe": ["pathe@2.0.3", "", {}, "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w=="],
|
||||
@@ -360,10 +316,6 @@
|
||||
|
||||
"react-reconciler": ["react-reconciler@0.32.0", "", { "dependencies": { "scheduler": "^0.26.0" }, "peerDependencies": { "react": "^19.1.0" } }, "sha512-2NPMOzgTlG0ZWdIf3qG+dcbLSoAc/uLfOwckc3ofy5sSK0pLJqnQLpUFxvGcN2rlXSjnVtGeeFLNimCQEj5gOQ=="],
|
||||
|
||||
"redeyed": ["redeyed@2.1.1", "", { "dependencies": { "esprima": "~4.0.0" } }, "sha512-FNpGGo1DycYAdnrKFxCMmKYgo/mILAqtRYbkdQD8Ep/Hk2PQ5+aEAEx+IU713RTDmuBaH0c8P5ZozurNu5ObRQ=="],
|
||||
|
||||
"require-directory": ["require-directory@2.1.1", "", {}, "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q=="],
|
||||
|
||||
"restore-cursor": ["restore-cursor@4.0.0", "", { "dependencies": { "onetime": "^5.1.0", "signal-exit": "^3.0.2" } }, "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg=="],
|
||||
|
||||
"rollup": ["rollup@4.52.0", "", { "dependencies": { "@types/estree": "1.0.8" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.52.0", "@rollup/rollup-android-arm64": "4.52.0", "@rollup/rollup-darwin-arm64": "4.52.0", "@rollup/rollup-darwin-x64": "4.52.0", "@rollup/rollup-freebsd-arm64": "4.52.0", "@rollup/rollup-freebsd-x64": "4.52.0", "@rollup/rollup-linux-arm-gnueabihf": "4.52.0", "@rollup/rollup-linux-arm-musleabihf": "4.52.0", "@rollup/rollup-linux-arm64-gnu": "4.52.0", "@rollup/rollup-linux-arm64-musl": "4.52.0", "@rollup/rollup-linux-loong64-gnu": "4.52.0", "@rollup/rollup-linux-ppc64-gnu": "4.52.0", "@rollup/rollup-linux-riscv64-gnu": "4.52.0", "@rollup/rollup-linux-riscv64-musl": "4.52.0", "@rollup/rollup-linux-s390x-gnu": "4.52.0", "@rollup/rollup-linux-x64-gnu": "4.52.0", "@rollup/rollup-linux-x64-musl": "4.52.0", "@rollup/rollup-openharmony-arm64": "4.52.0", "@rollup/rollup-win32-arm64-msvc": "4.52.0", "@rollup/rollup-win32-ia32-msvc": "4.52.0", "@rollup/rollup-win32-x64-gnu": "4.52.0", "@rollup/rollup-win32-x64-msvc": "4.52.0", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-+IuescNkTJQgX7AkIDtITipZdIGcWF0pnVvZTWStiazUmcGA2ag8dfg0urest2XlXUi9kuhfQ+qmdc5Stc3z7g=="],
|
||||
@@ -382,8 +334,6 @@
|
||||
|
||||
"stackback": ["stackback@0.0.2", "", {}, "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw=="],
|
||||
|
||||
"starknet": ["starknet@8.9.0", "", { "dependencies": { "@noble/curves": "~1.7.0", "@noble/hashes": "~1.6.0", "@scure/base": "~1.2.1", "@scure/starknet": "1.1.0", "@starknet-io/starknet-types-08": "npm:@starknet-io/types-js@~0.8.4", "@starknet-io/starknet-types-09": "npm:@starknet-io/types-js@~0.9.1", "abi-wan-kanabi": "2.2.4", "lossless-json": "^4.2.0", "pako": "^2.0.4", "ts-mixer": "^6.0.3" } }, "sha512-uhXSCKW0SMBGckd4yVlscVz4DMkQqZ+/RTpfxZ5J46e6AuCUHOqGKv61tqgUP9GhdvgHV/XyN+kdmlyZn3rXjA=="],
|
||||
|
||||
"std-env": ["std-env@3.9.0", "", {}, "sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw=="],
|
||||
|
||||
"string-width": ["string-width@7.2.0", "", { "dependencies": { "emoji-regex": "^10.3.0", "get-east-asian-width": "^1.0.0", "strip-ansi": "^7.1.0" } }, "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ=="],
|
||||
@@ -404,16 +354,12 @@
|
||||
|
||||
"tinyspy": ["tinyspy@4.0.4", "", {}, "sha512-azl+t0z7pw/z958Gy9svOTuzqIk6xq+NSheJzn5MMWtWTFywIacg2wUlzKFGtt3cthx0r2SxMK0yzJOR0IES7Q=="],
|
||||
|
||||
"ts-mixer": ["ts-mixer@6.0.4", "", {}, "sha512-ufKpbmrugz5Aou4wcr5Wc1UUFWOLhq+Fm6qa6P0w0K5Qw2yhaUoiWszhCVuNQyNwrlGiscHOmqYoAox1PtvgjA=="],
|
||||
|
||||
"type-fest": ["type-fest@4.41.0", "", {}, "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA=="],
|
||||
|
||||
"typescript": ["typescript@5.9.2", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A=="],
|
||||
|
||||
"undici-types": ["undici-types@7.12.0", "", {}, "sha512-goOacqME2GYyOZZfb5Lgtu+1IDmAlAEu5xnD3+xTzS10hT0vzpf0SPjkXwAw9Jm+4n/mQGDP3LO8CPbYROeBfQ=="],
|
||||
|
||||
"universalify": ["universalify@2.0.1", "", {}, "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw=="],
|
||||
|
||||
"vite": ["vite@7.1.7", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rollup": "^4.43.0", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", "less": "^4.0.0", "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-VbA8ScMvAISJNJVbRDTJdCwqQoAareR/wutevKanhR2/1EkoXVZVkkORaYm/tNVCjP/UDTKtcw3bAkwOUdedmA=="],
|
||||
|
||||
"vite-node": ["vite-node@3.2.4", "", { "dependencies": { "cac": "^6.7.14", "debug": "^4.4.1", "es-module-lexer": "^1.7.0", "pathe": "^2.0.3", "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" }, "bin": { "vite-node": "vite-node.mjs" } }, "sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg=="],
|
||||
@@ -428,56 +374,10 @@
|
||||
|
||||
"ws": ["ws@8.18.3", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg=="],
|
||||
|
||||
"y18n": ["y18n@5.0.8", "", {}, "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA=="],
|
||||
|
||||
"yargs": ["yargs@17.7.2", "", { "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", "string-width": "^4.2.3", "y18n": "^5.0.5", "yargs-parser": "^21.1.1" } }, "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w=="],
|
||||
|
||||
"yargs-parser": ["yargs-parser@21.1.1", "", {}, "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw=="],
|
||||
|
||||
"yoga-layout": ["yoga-layout@3.2.1", "", {}, "sha512-0LPOt3AxKqMdFBZA3HBAt/t/8vIKq7VaQYbuA8WxCgung+p9TVyKRYdpvCb80HcdTN2NkbIKbhNwKUfm3tQywQ=="],
|
||||
|
||||
"@scure/bip32/@scure/base": ["@scure/base@1.1.9", "", {}, "sha512-8YKhl8GHiNI/pU2VMaofa2Tor7PJRAjwQLBBuilkJ9L5+13yVbC7JO/wS7piioAvPSwR3JKM1IJ/u4xQzbcXKg=="],
|
||||
|
||||
"@scure/bip39/@scure/base": ["@scure/base@1.1.9", "", {}, "sha512-8YKhl8GHiNI/pU2VMaofa2Tor7PJRAjwQLBBuilkJ9L5+13yVbC7JO/wS7piioAvPSwR3JKM1IJ/u4xQzbcXKg=="],
|
||||
|
||||
"@scure/starknet/@noble/curves": ["@noble/curves@1.7.0", "", { "dependencies": { "@noble/hashes": "1.6.0" } }, "sha512-UTMhXK9SeDhFJVrHeUJ5uZlI6ajXg10O6Ddocf9S6GjbSBVZsJo88HzKwXznNfGpMTRDyJkqMjNDPYgf0qFWnw=="],
|
||||
|
||||
"@scure/starknet/@noble/hashes": ["@noble/hashes@1.6.1", "", {}, "sha512-pq5D8h10hHBjyqX+cfBm0i8JUXJ0UhczFc4r74zbuT9XgewFo2E3J1cOaGtdZynILNmQ685YWGzGE1Zv6io50w=="],
|
||||
|
||||
"cli-truncate/slice-ansi": ["slice-ansi@5.0.0", "", { "dependencies": { "ansi-styles": "^6.0.0", "is-fullwidth-code-point": "^4.0.0" } }, "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ=="],
|
||||
|
||||
"cliui/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="],
|
||||
|
||||
"cliui/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
|
||||
|
||||
"cliui/wrap-ansi": ["wrap-ansi@7.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="],
|
||||
|
||||
"starknet/@noble/curves": ["@noble/curves@1.7.0", "", { "dependencies": { "@noble/hashes": "1.6.0" } }, "sha512-UTMhXK9SeDhFJVrHeUJ5uZlI6ajXg10O6Ddocf9S6GjbSBVZsJo88HzKwXznNfGpMTRDyJkqMjNDPYgf0qFWnw=="],
|
||||
|
||||
"starknet/@noble/hashes": ["@noble/hashes@1.6.1", "", {}, "sha512-pq5D8h10hHBjyqX+cfBm0i8JUXJ0UhczFc4r74zbuT9XgewFo2E3J1cOaGtdZynILNmQ685YWGzGE1Zv6io50w=="],
|
||||
|
||||
"yargs/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="],
|
||||
|
||||
"@scure/starknet/@noble/curves/@noble/hashes": ["@noble/hashes@1.6.0", "", {}, "sha512-YUULf0Uk4/mAA89w+k3+yUYh6NrEvxZa5T6SY3wlMvE2chHkxFUUIDI8/XW1QSC357iA5pSnqt7XEhvFOqmDyQ=="],
|
||||
|
||||
"cli-truncate/slice-ansi/is-fullwidth-code-point": ["is-fullwidth-code-point@4.0.0", "", {}, "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ=="],
|
||||
|
||||
"cliui/string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="],
|
||||
|
||||
"cliui/string-width/is-fullwidth-code-point": ["is-fullwidth-code-point@3.0.0", "", {}, "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="],
|
||||
|
||||
"cliui/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
|
||||
|
||||
"cliui/wrap-ansi/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
|
||||
|
||||
"starknet/@noble/curves/@noble/hashes": ["@noble/hashes@1.6.0", "", {}, "sha512-YUULf0Uk4/mAA89w+k3+yUYh6NrEvxZa5T6SY3wlMvE2chHkxFUUIDI8/XW1QSC357iA5pSnqt7XEhvFOqmDyQ=="],
|
||||
|
||||
"yargs/string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="],
|
||||
|
||||
"yargs/string-width/is-fullwidth-code-point": ["is-fullwidth-code-point@3.0.0", "", {}, "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="],
|
||||
|
||||
"yargs/string-width/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
|
||||
|
||||
"yargs/string-width/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,4 +0,0 @@
|
||||
.idea
|
||||
vendor
|
||||
build/*
|
||||
!build/.keep
|
||||
@@ -1,9 +0,0 @@
|
||||
# lighter-go
|
||||
|
||||
In its current form, this repo serves as a starting point for anyone who wants to trade on Lighter using GO.
|
||||
It covers all the signing procedures in order to trade on Lighter with an API key.
|
||||
Minimal HTTP calls are implemented
|
||||
On chain support, like depositing on Ethereum or modifying an API key directly with an Ethereum Tx are not supported yet.
|
||||
|
||||
At the moment, its main purpose is to offer visibility on the code behind the precompiled libraries used by the Python SDK.
|
||||
If you'd like to compile your own binaries, the commands are in the `justfile`
|
||||
@@ -1,659 +0,0 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/elliottech/lighter-go/signer"
|
||||
"github.com/elliottech/lighter-go/types/txtypes"
|
||||
g "github.com/elliottech/poseidon_crypto/field/goldilocks"
|
||||
gFp5 "github.com/elliottech/poseidon_crypto/field/goldilocks_quintic_extension"
|
||||
p2 "github.com/elliottech/poseidon_crypto/hash/poseidon2_goldilocks"
|
||||
ethCommon "github.com/ethereum/go-ethereum/common"
|
||||
)
|
||||
|
||||
type TransactOpts struct {
|
||||
FromAccountIndex *int64
|
||||
ApiKeyIndex *uint8
|
||||
ExpiredAt int64
|
||||
Nonce *int64
|
||||
DryRun bool
|
||||
}
|
||||
|
||||
type PublicKey = gFp5.Element
|
||||
|
||||
type ChangePubKeyReq struct {
|
||||
PubKey [40]byte
|
||||
}
|
||||
|
||||
type TransferTxReq struct {
|
||||
ToAccountIndex int64
|
||||
USDCAmount int64
|
||||
Fee int64
|
||||
Memo [32]byte
|
||||
}
|
||||
|
||||
type WithdrawTxReq struct {
|
||||
USDCAmount uint64
|
||||
}
|
||||
|
||||
type CreateOrderTxReq struct {
|
||||
MarketIndex uint8
|
||||
ClientOrderIndex int64
|
||||
BaseAmount int64
|
||||
Price uint32
|
||||
IsAsk uint8
|
||||
Type uint8
|
||||
TimeInForce uint8
|
||||
ReduceOnly uint8
|
||||
TriggerPrice uint32
|
||||
OrderExpiry int64
|
||||
}
|
||||
|
||||
type CreateGroupedOrdersTxReq struct {
|
||||
GroupingType uint8
|
||||
Orders []*CreateOrderTxReq
|
||||
}
|
||||
|
||||
type ModifyOrderTxReq struct {
|
||||
MarketIndex uint8
|
||||
Index int64
|
||||
BaseAmount int64
|
||||
Price uint32
|
||||
TriggerPrice uint32
|
||||
}
|
||||
|
||||
type CancelOrderTxReq struct {
|
||||
MarketIndex uint8
|
||||
Index int64
|
||||
}
|
||||
|
||||
type CancelAllOrdersTxReq struct {
|
||||
TimeInForce uint8
|
||||
Time int64
|
||||
}
|
||||
|
||||
type CreatePublicPoolTxReq struct {
|
||||
OperatorFee int64
|
||||
InitialTotalShares int64
|
||||
MinOperatorShareRate int64
|
||||
}
|
||||
|
||||
type UpdatePublicPoolTxReq struct {
|
||||
PublicPoolIndex int64
|
||||
Status uint8
|
||||
OperatorFee int64
|
||||
MinOperatorShareRate int64
|
||||
}
|
||||
|
||||
type MintSharesTxReq struct {
|
||||
PublicPoolIndex int64
|
||||
ShareAmount int64
|
||||
}
|
||||
|
||||
type BurnSharesTxReq struct {
|
||||
PublicPoolIndex int64
|
||||
ShareAmount int64
|
||||
}
|
||||
|
||||
type UpdateLeverageTxReq struct {
|
||||
MarketIndex uint8
|
||||
InitialMarginFraction uint16
|
||||
MarginMode uint8
|
||||
}
|
||||
|
||||
type UpdateMarginTxReq struct {
|
||||
MarketIndex uint8
|
||||
USDCAmount int64
|
||||
Direction uint8
|
||||
}
|
||||
|
||||
func ConstructAuthToken(key signer.Signer, deadline time.Time, ops *TransactOpts) (string, error) {
|
||||
if ops.FromAccountIndex == nil {
|
||||
return "", fmt.Errorf("missing FromAccountIndex")
|
||||
}
|
||||
if ops.ApiKeyIndex == nil {
|
||||
return "", fmt.Errorf("missing ApiKeyIndex")
|
||||
}
|
||||
message := fmt.Sprintf("%v:%v:%v", deadline.Unix(), *ops.FromAccountIndex, *ops.ApiKeyIndex)
|
||||
|
||||
msgInField, err := g.ArrayFromCanonicalLittleEndianBytes([]byte(message))
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to convert bytes to field element. message: %s, error: %w", message, err)
|
||||
}
|
||||
|
||||
msgHash := p2.HashToQuinticExtension(msgInField).ToLittleEndianBytes()
|
||||
|
||||
signatureBytes, err := key.Sign(msgHash, p2.NewPoseidon2())
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
signature := ethCommon.Bytes2Hex(signatureBytes)
|
||||
|
||||
return fmt.Sprintf("%v:%v", message, signature), err
|
||||
}
|
||||
|
||||
func ConstructChangePubKeyTx(key signer.Signer, lighterChainId uint32, tx *ChangePubKeyReq, ops *TransactOpts) (*txtypes.L2ChangePubKeyTxInfo, error) {
|
||||
convertedTx := ConvertChangePubKeyTx(tx, ops)
|
||||
err := convertedTx.Validate()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
msgHash, err := convertedTx.Hash(lighterChainId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
signature, err := key.Sign(msgHash, p2.NewPoseidon2())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
convertedTx.SignedHash = ethCommon.Bytes2Hex(msgHash)
|
||||
convertedTx.Sig = signature
|
||||
return convertedTx, nil
|
||||
}
|
||||
|
||||
func ConstructCreateSubAccountTx(key signer.Signer, lighterChainId uint32, ops *TransactOpts) (*txtypes.L2CreateSubAccountTxInfo, error) {
|
||||
convertedTx := ConvertCreateSubAccountTx(ops)
|
||||
err := convertedTx.Validate()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
msgHash, err := convertedTx.Hash(lighterChainId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
signature, err := key.Sign(msgHash, p2.NewPoseidon2())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
convertedTx.SignedHash = ethCommon.Bytes2Hex(msgHash)
|
||||
convertedTx.Sig = signature
|
||||
return convertedTx, nil
|
||||
}
|
||||
|
||||
func ConstructCreatePublicPoolTx(key signer.Signer, lighterChainId uint32, tx *CreatePublicPoolTxReq, ops *TransactOpts) (*txtypes.L2CreatePublicPoolTxInfo, error) {
|
||||
convertedTx := ConvertCreatePublicPoolTx(tx, ops)
|
||||
err := convertedTx.Validate()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
msgHash, err := convertedTx.Hash(lighterChainId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
signature, err := key.Sign(msgHash, p2.NewPoseidon2())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
convertedTx.SignedHash = ethCommon.Bytes2Hex(msgHash)
|
||||
convertedTx.Sig = signature
|
||||
return convertedTx, nil
|
||||
}
|
||||
|
||||
func ConstructUpdatePublicPoolTx(key signer.Signer, lighterChainId uint32, tx *UpdatePublicPoolTxReq, ops *TransactOpts) (*txtypes.L2UpdatePublicPoolTxInfo, error) {
|
||||
convertedTx := ConvertUpdatePublicPoolTx(tx, ops)
|
||||
err := convertedTx.Validate()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
msgHash, err := convertedTx.Hash(lighterChainId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
signature, err := key.Sign(msgHash, p2.NewPoseidon2())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
convertedTx.SignedHash = ethCommon.Bytes2Hex(msgHash)
|
||||
convertedTx.Sig = signature
|
||||
return convertedTx, nil
|
||||
}
|
||||
|
||||
func ConstructWithdrawTx(key signer.Signer, lighterChainId uint32, tx *WithdrawTxReq, ops *TransactOpts) (*txtypes.L2WithdrawTxInfo, error) {
|
||||
convertedTx := ConvertWithdrawTx(tx, ops)
|
||||
err := convertedTx.Validate()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
msgHash, err := convertedTx.Hash(lighterChainId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
signature, err := key.Sign(msgHash, p2.NewPoseidon2())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
convertedTx.SignedHash = ethCommon.Bytes2Hex(msgHash)
|
||||
convertedTx.Sig = signature
|
||||
return convertedTx, nil
|
||||
}
|
||||
|
||||
func ConstructCreateOrderTx(key signer.Signer, lighterChainId uint32, tx *CreateOrderTxReq, ops *TransactOpts) (*txtypes.L2CreateOrderTxInfo, error) {
|
||||
convertedTx := ConvertCreateOrderTx(tx, ops)
|
||||
err := convertedTx.Validate()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
msgHash, err := convertedTx.Hash(lighterChainId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
signature, err := key.Sign(msgHash, p2.NewPoseidon2())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
convertedTx.SignedHash = ethCommon.Bytes2Hex(msgHash)
|
||||
convertedTx.Sig = signature
|
||||
return convertedTx, nil
|
||||
}
|
||||
|
||||
func ConstructL2CreateGroupedOrdersTx(key signer.Signer, lighterChainId uint32, tx *CreateGroupedOrdersTxReq, ops *TransactOpts) (*txtypes.L2CreateGroupedOrdersTxInfo, error) {
|
||||
convertedTx := ConvertCreateGroupedOrdersTx(tx, ops)
|
||||
err := convertedTx.Validate()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
msgHash, err := convertedTx.Hash(lighterChainId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
signature, err := key.Sign(msgHash, p2.NewPoseidon2())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
convertedTx.SignedHash = ethCommon.Bytes2Hex(msgHash)
|
||||
convertedTx.Sig = signature
|
||||
return convertedTx, nil
|
||||
}
|
||||
|
||||
func ConstructL2CancelOrderTx(key signer.Signer, lighterChainId uint32, tx *CancelOrderTxReq, ops *TransactOpts) (*txtypes.L2CancelOrderTxInfo, error) {
|
||||
convertedTx := ConvertCancelOrderTx(tx, ops)
|
||||
err := convertedTx.Validate()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
msgHash, err := convertedTx.Hash(lighterChainId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
signature, err := key.Sign(msgHash, p2.NewPoseidon2())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
convertedTx.SignedHash = ethCommon.Bytes2Hex(msgHash)
|
||||
convertedTx.Sig = signature
|
||||
return convertedTx, nil
|
||||
}
|
||||
|
||||
func ConstructL2ModifyOrderTx(key signer.Signer, lighterChainId uint32, tx *ModifyOrderTxReq, ops *TransactOpts) (*txtypes.L2ModifyOrderTxInfo, error) {
|
||||
convertedTx := ConvertModifyOrderTx(tx, ops)
|
||||
err := convertedTx.Validate()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
msgHash, err := convertedTx.Hash(lighterChainId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
signature, err := key.Sign(msgHash, p2.NewPoseidon2())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
convertedTx.SignedHash = ethCommon.Bytes2Hex(msgHash)
|
||||
convertedTx.Sig = signature
|
||||
return convertedTx, nil
|
||||
}
|
||||
|
||||
func ConstructL2CancelAllOrdersTx(key signer.Signer, lighterChainId uint32, tx *CancelAllOrdersTxReq, ops *TransactOpts) (*txtypes.L2CancelAllOrdersTxInfo, error) {
|
||||
convertedTx := ConvertCancelAllOrdersTx(tx, ops)
|
||||
err := convertedTx.Validate()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
msgHash, err := convertedTx.Hash(lighterChainId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
signature, err := key.Sign(msgHash, p2.NewPoseidon2())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
convertedTx.SignedHash = ethCommon.Bytes2Hex(msgHash)
|
||||
convertedTx.Sig = signature
|
||||
return convertedTx, nil
|
||||
}
|
||||
|
||||
func ConstructTransferTx(key signer.Signer, lighterChainId uint32, tx *TransferTxReq, ops *TransactOpts) (*txtypes.L2TransferTxInfo, error) {
|
||||
convertedTx := ConvertTransferTx(tx, ops)
|
||||
err := convertedTx.Validate()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
msgHash, err := convertedTx.Hash(lighterChainId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
signature, err := key.Sign(msgHash, p2.NewPoseidon2())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
convertedTx.SignedHash = ethCommon.Bytes2Hex(msgHash)
|
||||
convertedTx.Sig = signature
|
||||
return convertedTx, nil
|
||||
}
|
||||
|
||||
func ConstructMintSharesTx(key signer.Signer, lighterChainId uint32, tx *MintSharesTxReq, ops *TransactOpts) (*txtypes.L2MintSharesTxInfo, error) {
|
||||
convertedTx := ConvertMintSharesTx(tx, ops)
|
||||
err := convertedTx.Validate()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
msgHash, err := convertedTx.Hash(lighterChainId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
signature, err := key.Sign(msgHash, p2.NewPoseidon2())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
convertedTx.SignedHash = ethCommon.Bytes2Hex(msgHash)
|
||||
convertedTx.Sig = signature
|
||||
return convertedTx, nil
|
||||
}
|
||||
|
||||
func ConstructBurnSharesTx(key signer.Signer, lighterChainId uint32, tx *BurnSharesTxReq, ops *TransactOpts) (*txtypes.L2BurnSharesTxInfo, error) {
|
||||
convertedTx := ConvertBurnSharesTx(tx, ops)
|
||||
err := convertedTx.Validate()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
msgHash, err := convertedTx.Hash(lighterChainId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
signature, err := key.Sign(msgHash, p2.NewPoseidon2())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
convertedTx.SignedHash = ethCommon.Bytes2Hex(msgHash)
|
||||
convertedTx.Sig = signature
|
||||
return convertedTx, nil
|
||||
}
|
||||
|
||||
func ConstructUpdateLeverageTx(key signer.Signer, lighterChainId uint32, tx *UpdateLeverageTxReq, ops *TransactOpts) (*txtypes.L2UpdateLeverageTxInfo, error) {
|
||||
convertedTx := ConvertUpdateLeverageTx(tx, ops)
|
||||
err := convertedTx.Validate()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
msgHash, err := convertedTx.Hash(lighterChainId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
signature, err := key.Sign(msgHash, p2.NewPoseidon2())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
convertedTx.SignedHash = ethCommon.Bytes2Hex(msgHash)
|
||||
convertedTx.Sig = signature
|
||||
return convertedTx, nil
|
||||
}
|
||||
|
||||
func ConstructUpdateMarginTx(key signer.Signer, lighterChainId uint32, tx *UpdateMarginTxReq, ops *TransactOpts) (*txtypes.L2UpdateMarginTxInfo, error) {
|
||||
convertedTx := ConvertUpdateMarginTx(tx, ops)
|
||||
err := convertedTx.Validate()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
msgHash, err := convertedTx.Hash(lighterChainId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
signature, err := key.Sign(msgHash, p2.NewPoseidon2())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
convertedTx.SignedHash = ethCommon.Bytes2Hex(msgHash)
|
||||
convertedTx.Sig = signature
|
||||
return convertedTx, nil
|
||||
}
|
||||
|
||||
func ConvertTransferTx(tx *TransferTxReq, ops *TransactOpts) *txtypes.L2TransferTxInfo {
|
||||
return &txtypes.L2TransferTxInfo{
|
||||
FromAccountIndex: *ops.FromAccountIndex,
|
||||
ApiKeyIndex: *ops.ApiKeyIndex,
|
||||
ToAccountIndex: tx.ToAccountIndex,
|
||||
USDCAmount: tx.USDCAmount,
|
||||
Fee: tx.Fee,
|
||||
Memo: tx.Memo,
|
||||
ExpiredAt: ops.ExpiredAt,
|
||||
Nonce: *ops.Nonce,
|
||||
}
|
||||
}
|
||||
|
||||
func ConvertCreateOrderTx(tx *CreateOrderTxReq, ops *TransactOpts) *txtypes.L2CreateOrderTxInfo {
|
||||
return &txtypes.L2CreateOrderTxInfo{
|
||||
AccountIndex: *ops.FromAccountIndex,
|
||||
ApiKeyIndex: *ops.ApiKeyIndex,
|
||||
OrderInfo: &txtypes.OrderInfo{MarketIndex: tx.MarketIndex,
|
||||
ClientOrderIndex: tx.ClientOrderIndex,
|
||||
BaseAmount: tx.BaseAmount,
|
||||
Price: tx.Price,
|
||||
IsAsk: tx.IsAsk,
|
||||
Type: tx.Type,
|
||||
TimeInForce: tx.TimeInForce,
|
||||
ReduceOnly: tx.ReduceOnly,
|
||||
TriggerPrice: tx.TriggerPrice,
|
||||
OrderExpiry: tx.OrderExpiry,
|
||||
},
|
||||
ExpiredAt: ops.ExpiredAt,
|
||||
Nonce: *ops.Nonce,
|
||||
}
|
||||
}
|
||||
|
||||
func ConvertCreateGroupedOrdersTx(tx *CreateGroupedOrdersTxReq, ops *TransactOpts) *txtypes.L2CreateGroupedOrdersTxInfo {
|
||||
ret := &txtypes.L2CreateGroupedOrdersTxInfo{
|
||||
AccountIndex: *ops.FromAccountIndex,
|
||||
ApiKeyIndex: *ops.ApiKeyIndex,
|
||||
GroupingType: tx.GroupingType,
|
||||
Orders: []*txtypes.OrderInfo{},
|
||||
ExpiredAt: ops.ExpiredAt,
|
||||
Nonce: *ops.Nonce,
|
||||
}
|
||||
|
||||
for _, order := range tx.Orders {
|
||||
ret.Orders = append(ret.Orders, &txtypes.OrderInfo{
|
||||
MarketIndex: order.MarketIndex,
|
||||
ClientOrderIndex: order.ClientOrderIndex,
|
||||
BaseAmount: order.BaseAmount,
|
||||
Price: order.Price,
|
||||
IsAsk: order.IsAsk,
|
||||
Type: order.Type,
|
||||
TimeInForce: order.TimeInForce,
|
||||
ReduceOnly: order.ReduceOnly,
|
||||
TriggerPrice: order.TriggerPrice,
|
||||
OrderExpiry: order.OrderExpiry,
|
||||
})
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func ConvertCancelOrderTx(tx *CancelOrderTxReq, ops *TransactOpts) *txtypes.L2CancelOrderTxInfo {
|
||||
return &txtypes.L2CancelOrderTxInfo{
|
||||
AccountIndex: *ops.FromAccountIndex,
|
||||
ApiKeyIndex: *ops.ApiKeyIndex,
|
||||
MarketIndex: tx.MarketIndex,
|
||||
Index: tx.Index,
|
||||
ExpiredAt: ops.ExpiredAt,
|
||||
Nonce: *ops.Nonce,
|
||||
}
|
||||
}
|
||||
|
||||
func ConvertModifyOrderTx(tx *ModifyOrderTxReq, ops *TransactOpts) *txtypes.L2ModifyOrderTxInfo {
|
||||
return &txtypes.L2ModifyOrderTxInfo{
|
||||
AccountIndex: *ops.FromAccountIndex,
|
||||
ApiKeyIndex: *ops.ApiKeyIndex,
|
||||
MarketIndex: tx.MarketIndex,
|
||||
Index: tx.Index,
|
||||
BaseAmount: tx.BaseAmount,
|
||||
Price: tx.Price,
|
||||
TriggerPrice: tx.TriggerPrice,
|
||||
ExpiredAt: ops.ExpiredAt,
|
||||
Nonce: *ops.Nonce,
|
||||
}
|
||||
}
|
||||
|
||||
func ConvertCancelAllOrdersTx(tx *CancelAllOrdersTxReq, ops *TransactOpts) *txtypes.L2CancelAllOrdersTxInfo {
|
||||
return &txtypes.L2CancelAllOrdersTxInfo{
|
||||
AccountIndex: *ops.FromAccountIndex,
|
||||
ApiKeyIndex: *ops.ApiKeyIndex,
|
||||
TimeInForce: tx.TimeInForce,
|
||||
Time: tx.Time,
|
||||
ExpiredAt: ops.ExpiredAt,
|
||||
Nonce: *ops.Nonce,
|
||||
}
|
||||
}
|
||||
|
||||
func ConvertWithdrawTx(tx *WithdrawTxReq, ops *TransactOpts) *txtypes.L2WithdrawTxInfo {
|
||||
return &txtypes.L2WithdrawTxInfo{
|
||||
FromAccountIndex: *ops.FromAccountIndex,
|
||||
ApiKeyIndex: *ops.ApiKeyIndex,
|
||||
USDCAmount: tx.USDCAmount,
|
||||
ExpiredAt: ops.ExpiredAt,
|
||||
Nonce: *ops.Nonce,
|
||||
}
|
||||
}
|
||||
|
||||
func ConvertChangePubKeyTx(tx *ChangePubKeyReq, ops *TransactOpts) *txtypes.L2ChangePubKeyTxInfo {
|
||||
return &txtypes.L2ChangePubKeyTxInfo{
|
||||
AccountIndex: *ops.FromAccountIndex,
|
||||
ApiKeyIndex: *ops.ApiKeyIndex,
|
||||
PubKey: tx.PubKey[:],
|
||||
ExpiredAt: ops.ExpiredAt,
|
||||
Nonce: *ops.Nonce,
|
||||
}
|
||||
}
|
||||
|
||||
func ConvertCreateSubAccountTx(ops *TransactOpts) *txtypes.L2CreateSubAccountTxInfo {
|
||||
return &txtypes.L2CreateSubAccountTxInfo{
|
||||
AccountIndex: *ops.FromAccountIndex,
|
||||
ApiKeyIndex: *ops.ApiKeyIndex,
|
||||
ExpiredAt: ops.ExpiredAt,
|
||||
Nonce: *ops.Nonce,
|
||||
}
|
||||
}
|
||||
|
||||
func ConvertCreatePublicPoolTx(tx *CreatePublicPoolTxReq, ops *TransactOpts) *txtypes.L2CreatePublicPoolTxInfo {
|
||||
return &txtypes.L2CreatePublicPoolTxInfo{
|
||||
AccountIndex: *ops.FromAccountIndex,
|
||||
ApiKeyIndex: *ops.ApiKeyIndex,
|
||||
OperatorFee: tx.OperatorFee,
|
||||
InitialTotalShares: tx.InitialTotalShares,
|
||||
MinOperatorShareRate: tx.MinOperatorShareRate,
|
||||
ExpiredAt: ops.ExpiredAt,
|
||||
Nonce: *ops.Nonce,
|
||||
}
|
||||
}
|
||||
|
||||
func ConvertUpdatePublicPoolTx(tx *UpdatePublicPoolTxReq, ops *TransactOpts) *txtypes.L2UpdatePublicPoolTxInfo {
|
||||
return &txtypes.L2UpdatePublicPoolTxInfo{
|
||||
AccountIndex: *ops.FromAccountIndex,
|
||||
ApiKeyIndex: *ops.ApiKeyIndex,
|
||||
PublicPoolIndex: tx.PublicPoolIndex,
|
||||
Status: tx.Status,
|
||||
OperatorFee: tx.OperatorFee,
|
||||
MinOperatorShareRate: tx.MinOperatorShareRate,
|
||||
ExpiredAt: ops.ExpiredAt,
|
||||
Nonce: *ops.Nonce,
|
||||
}
|
||||
}
|
||||
|
||||
func ConvertMintSharesTx(tx *MintSharesTxReq, ops *TransactOpts) *txtypes.L2MintSharesTxInfo {
|
||||
return &txtypes.L2MintSharesTxInfo{
|
||||
AccountIndex: *ops.FromAccountIndex,
|
||||
ApiKeyIndex: *ops.ApiKeyIndex,
|
||||
PublicPoolIndex: tx.PublicPoolIndex,
|
||||
ShareAmount: tx.ShareAmount,
|
||||
ExpiredAt: ops.ExpiredAt,
|
||||
Nonce: *ops.Nonce,
|
||||
}
|
||||
}
|
||||
|
||||
func ConvertBurnSharesTx(tx *BurnSharesTxReq, ops *TransactOpts) *txtypes.L2BurnSharesTxInfo {
|
||||
return &txtypes.L2BurnSharesTxInfo{
|
||||
AccountIndex: *ops.FromAccountIndex,
|
||||
ApiKeyIndex: *ops.ApiKeyIndex,
|
||||
PublicPoolIndex: tx.PublicPoolIndex,
|
||||
ShareAmount: tx.ShareAmount,
|
||||
ExpiredAt: ops.ExpiredAt,
|
||||
Nonce: *ops.Nonce,
|
||||
}
|
||||
}
|
||||
|
||||
func ConvertUpdateLeverageTx(tx *UpdateLeverageTxReq, ops *TransactOpts) *txtypes.L2UpdateLeverageTxInfo {
|
||||
return &txtypes.L2UpdateLeverageTxInfo{
|
||||
AccountIndex: *ops.FromAccountIndex,
|
||||
ApiKeyIndex: *ops.ApiKeyIndex,
|
||||
MarketIndex: tx.MarketIndex,
|
||||
InitialMarginFraction: tx.InitialMarginFraction,
|
||||
ExpiredAt: ops.ExpiredAt,
|
||||
Nonce: *ops.Nonce,
|
||||
}
|
||||
}
|
||||
|
||||
func ConvertUpdateMarginTx(tx *UpdateMarginTxReq, ops *TransactOpts) *txtypes.L2UpdateMarginTxInfo {
|
||||
return &txtypes.L2UpdateMarginTxInfo{
|
||||
AccountIndex: *ops.FromAccountIndex,
|
||||
ApiKeyIndex: *ops.ApiKeyIndex,
|
||||
MarketIndex: tx.MarketIndex,
|
||||
USDCAmount: tx.USDCAmount,
|
||||
Direction: tx.Direction,
|
||||
ExpiredAt: ops.ExpiredAt,
|
||||
Nonce: *ops.Nonce,
|
||||
}
|
||||
}
|
||||
@@ -1,91 +0,0 @@
|
||||
package txtypes
|
||||
|
||||
import (
|
||||
g "github.com/elliottech/poseidon_crypto/field/goldilocks"
|
||||
p2 "github.com/elliottech/poseidon_crypto/hash/poseidon2_goldilocks"
|
||||
)
|
||||
|
||||
var _ TxInfo = (*L2BurnSharesTxInfo)(nil)
|
||||
|
||||
type L2BurnSharesTxInfo struct {
|
||||
AccountIndex int64
|
||||
ApiKeyIndex uint8
|
||||
|
||||
PublicPoolIndex int64
|
||||
ShareAmount int64
|
||||
|
||||
ExpiredAt int64
|
||||
Nonce int64
|
||||
Sig []byte
|
||||
SignedHash string `json:"-"`
|
||||
}
|
||||
|
||||
func (txInfo *L2BurnSharesTxInfo) GetTxType() uint8 {
|
||||
return TxTypeL2BurnShares
|
||||
}
|
||||
|
||||
func (txInfo *L2BurnSharesTxInfo) GetTxInfo() (string, error) {
|
||||
return getTxInfo(txInfo)
|
||||
}
|
||||
|
||||
func (txInfo *L2BurnSharesTxInfo) GetTxHash() string {
|
||||
return txInfo.SignedHash
|
||||
}
|
||||
|
||||
func (txInfo *L2BurnSharesTxInfo) Validate() error {
|
||||
if txInfo.AccountIndex < MinAccountIndex {
|
||||
return ErrFromAccountIndexTooLow
|
||||
}
|
||||
if txInfo.AccountIndex > MaxAccountIndex {
|
||||
return ErrFromAccountIndexTooHigh
|
||||
}
|
||||
|
||||
// ApiKeyIndex
|
||||
if txInfo.ApiKeyIndex < MinApiKeyIndex {
|
||||
return ErrApiKeyIndexTooLow
|
||||
}
|
||||
if txInfo.ApiKeyIndex > MaxApiKeyIndex {
|
||||
return ErrApiKeyIndexTooHigh
|
||||
}
|
||||
|
||||
// PublicPoolIndex
|
||||
if txInfo.PublicPoolIndex < MinAccountIndex {
|
||||
return ErrPublicPoolIndexTooLow
|
||||
}
|
||||
if txInfo.PublicPoolIndex > MaxAccountIndex {
|
||||
return ErrPublicPoolIndexTooHigh
|
||||
}
|
||||
|
||||
if txInfo.ShareAmount < MinPoolSharesToMintOrBurn {
|
||||
return ErrPoolBurnShareAmountTooLow
|
||||
}
|
||||
if txInfo.ShareAmount > MaxPoolSharesToMintOrBurn {
|
||||
return ErrPoolBurnShareAmountTooHigh
|
||||
}
|
||||
|
||||
if txInfo.Nonce < MinNonce {
|
||||
return ErrNonceTooLow
|
||||
}
|
||||
|
||||
if txInfo.ExpiredAt < 0 || txInfo.ExpiredAt > MaxTimestamp {
|
||||
return ErrExpiredAtInvalid
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (txInfo *L2BurnSharesTxInfo) Hash(lighterChainId uint32, extra ...g.Element) (msgHash []byte, err error) {
|
||||
elems := make([]g.Element, 0, 8)
|
||||
|
||||
elems = append(elems, g.FromUint32(lighterChainId))
|
||||
elems = append(elems, g.FromUint32(TxTypeL2BurnShares))
|
||||
elems = append(elems, g.FromInt64(txInfo.Nonce))
|
||||
elems = append(elems, g.FromInt64(txInfo.ExpiredAt))
|
||||
|
||||
elems = append(elems, g.FromInt64(txInfo.AccountIndex))
|
||||
elems = append(elems, g.FromUint32(uint32(txInfo.ApiKeyIndex)))
|
||||
elems = append(elems, g.FromInt64(txInfo.PublicPoolIndex))
|
||||
elems = append(elems, g.FromInt64(txInfo.ShareAmount))
|
||||
|
||||
return p2.HashToQuinticExtension(elems).ToLittleEndianBytes(), nil
|
||||
}
|
||||
@@ -1,95 +0,0 @@
|
||||
package txtypes
|
||||
|
||||
import (
|
||||
g "github.com/elliottech/poseidon_crypto/field/goldilocks"
|
||||
p2 "github.com/elliottech/poseidon_crypto/hash/poseidon2_goldilocks"
|
||||
)
|
||||
|
||||
var _ TxInfo = (*L2CancelAllOrdersTxInfo)(nil)
|
||||
|
||||
type L2CancelAllOrdersTxInfo struct {
|
||||
AccountIndex int64
|
||||
ApiKeyIndex uint8
|
||||
|
||||
TimeInForce uint8
|
||||
Time int64
|
||||
|
||||
ExpiredAt int64
|
||||
Nonce int64
|
||||
Sig []byte
|
||||
SignedHash string `json:"-"`
|
||||
}
|
||||
|
||||
func (txInfo *L2CancelAllOrdersTxInfo) GetTxType() uint8 {
|
||||
return TxTypeL2CancelAllOrders
|
||||
}
|
||||
|
||||
func (txInfo *L2CancelAllOrdersTxInfo) GetTxInfo() (string, error) {
|
||||
return getTxInfo(txInfo)
|
||||
}
|
||||
|
||||
func (txInfo *L2CancelAllOrdersTxInfo) GetTxHash() string {
|
||||
return txInfo.SignedHash
|
||||
}
|
||||
|
||||
func (txInfo *L2CancelAllOrdersTxInfo) Validate() error {
|
||||
// AccountIndex
|
||||
if txInfo.AccountIndex < MinAccountIndex {
|
||||
return ErrAccountIndexTooLow
|
||||
}
|
||||
if txInfo.AccountIndex > MaxAccountIndex {
|
||||
return ErrAccountIndexTooHigh
|
||||
}
|
||||
|
||||
if txInfo.ApiKeyIndex < MinApiKeyIndex {
|
||||
return ErrApiKeyIndexTooLow
|
||||
}
|
||||
if txInfo.ApiKeyIndex > MaxApiKeyIndex && txInfo.ApiKeyIndex != NilApiKeyIndex {
|
||||
return ErrApiKeyIndexTooHigh
|
||||
}
|
||||
|
||||
// Nonce
|
||||
if txInfo.Nonce < MinNonce {
|
||||
return ErrNonceTooLow
|
||||
}
|
||||
|
||||
if txInfo.ExpiredAt < 0 || txInfo.ExpiredAt > MaxTimestamp {
|
||||
return ErrExpiredAtInvalid
|
||||
}
|
||||
|
||||
// TimeInForce and Time
|
||||
switch txInfo.TimeInForce {
|
||||
case ImmediateCancelAll:
|
||||
if txInfo.Time != NilOrderExpiry {
|
||||
return ErrCancelAllTimeisNotNill
|
||||
}
|
||||
case ScheduledCancelAll:
|
||||
if txInfo.Time < MinOrderExpiry || txInfo.Time > MaxOrderExpiry {
|
||||
return ErrCancelAllTimeIsNotInRange
|
||||
}
|
||||
case AbortScheduledCancelAll:
|
||||
if txInfo.Time != 0 {
|
||||
return ErrCancelAllTimeIsNotInRange
|
||||
}
|
||||
default:
|
||||
return ErrInvalidCancelAllTimeInForce
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (txInfo *L2CancelAllOrdersTxInfo) Hash(lighterChainId uint32, extra ...g.Element) (msgHash []byte, err error) {
|
||||
elems := make([]g.Element, 0, 8)
|
||||
|
||||
elems = append(elems, g.FromUint32(lighterChainId))
|
||||
elems = append(elems, g.FromUint32(TxTypeL2CancelAllOrders))
|
||||
elems = append(elems, g.FromInt64(txInfo.Nonce))
|
||||
elems = append(elems, g.FromInt64(txInfo.ExpiredAt))
|
||||
|
||||
elems = append(elems, g.FromInt64(txInfo.AccountIndex))
|
||||
elems = append(elems, g.FromUint32(uint32(txInfo.ApiKeyIndex)))
|
||||
elems = append(elems, g.FromUint32(uint32(txInfo.TimeInForce)))
|
||||
elems = append(elems, g.FromInt64(txInfo.Time))
|
||||
|
||||
return p2.HashToQuinticExtension(elems).ToLittleEndianBytes(), nil
|
||||
}
|
||||
@@ -1,94 +0,0 @@
|
||||
package txtypes
|
||||
|
||||
import (
|
||||
g "github.com/elliottech/poseidon_crypto/field/goldilocks"
|
||||
p2 "github.com/elliottech/poseidon_crypto/hash/poseidon2_goldilocks"
|
||||
)
|
||||
|
||||
var _ TxInfo = (*L2CancelOrderTxInfo)(nil)
|
||||
|
||||
type L2CancelOrderTxInfo struct {
|
||||
AccountIndex int64
|
||||
ApiKeyIndex uint8
|
||||
|
||||
MarketIndex uint8
|
||||
Index int64 // Client Order Index or Order Index of the order to cancel
|
||||
|
||||
ExpiredAt int64
|
||||
Nonce int64
|
||||
Sig []byte
|
||||
SignedHash string `json:"-"`
|
||||
}
|
||||
|
||||
func (txInfo *L2CancelOrderTxInfo) GetTxType() uint8 {
|
||||
return TxTypeL2CancelOrder
|
||||
}
|
||||
|
||||
func (txInfo *L2CancelOrderTxInfo) GetTxInfo() (string, error) {
|
||||
return getTxInfo(txInfo)
|
||||
}
|
||||
|
||||
func (txInfo *L2CancelOrderTxInfo) GetTxHash() string {
|
||||
return txInfo.SignedHash
|
||||
}
|
||||
|
||||
func (txInfo *L2CancelOrderTxInfo) Validate() error {
|
||||
// AccountIndex
|
||||
if txInfo.AccountIndex < MinAccountIndex {
|
||||
return ErrAccountIndexTooLow
|
||||
}
|
||||
if txInfo.AccountIndex > MaxAccountIndex {
|
||||
return ErrAccountIndexTooHigh
|
||||
}
|
||||
|
||||
// ApiKeyIndex
|
||||
if txInfo.ApiKeyIndex < MinApiKeyIndex {
|
||||
return ErrApiKeyIndexTooLow
|
||||
}
|
||||
if txInfo.ApiKeyIndex > MaxApiKeyIndex {
|
||||
return ErrApiKeyIndexTooHigh
|
||||
}
|
||||
|
||||
// MarketIndex
|
||||
if txInfo.MarketIndex < MinMarketIndex {
|
||||
return ErrMarketIndexTooLow
|
||||
}
|
||||
if txInfo.MarketIndex > MaxMarketIndex {
|
||||
return ErrMarketIndexTooHigh
|
||||
}
|
||||
|
||||
// Index
|
||||
if txInfo.Index < MinClientOrderIndex && txInfo.Index < MinOrderIndex {
|
||||
return ErrOrderIndexTooLow
|
||||
}
|
||||
if txInfo.Index > MaxClientOrderIndex && txInfo.Index > MaxOrderIndex {
|
||||
return ErrOrderIndexTooHigh
|
||||
}
|
||||
|
||||
// Nonce
|
||||
if txInfo.Nonce < MinNonce {
|
||||
return ErrNonceTooLow
|
||||
}
|
||||
|
||||
if txInfo.ExpiredAt < 0 || txInfo.ExpiredAt > MaxTimestamp {
|
||||
return ErrExpiredAtInvalid
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (txInfo *L2CancelOrderTxInfo) Hash(lighterChainId uint32, extra ...g.Element) (msgHash []byte, err error) {
|
||||
elems := make([]g.Element, 0, 7)
|
||||
|
||||
elems = append(elems, g.FromUint32(lighterChainId))
|
||||
elems = append(elems, g.FromUint32(TxTypeL2CancelOrder))
|
||||
elems = append(elems, g.FromInt64(txInfo.Nonce))
|
||||
elems = append(elems, g.FromInt64(txInfo.ExpiredAt))
|
||||
|
||||
elems = append(elems, g.FromInt64(txInfo.AccountIndex))
|
||||
elems = append(elems, g.FromUint32(uint32(txInfo.ApiKeyIndex)))
|
||||
elems = append(elems, g.FromUint32(uint32(txInfo.MarketIndex)))
|
||||
elems = append(elems, g.FromInt64(txInfo.Index))
|
||||
|
||||
return p2.HashToQuinticExtension(elems).ToLittleEndianBytes(), nil
|
||||
}
|
||||
@@ -1,121 +0,0 @@
|
||||
package txtypes
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
g "github.com/elliottech/poseidon_crypto/field/goldilocks"
|
||||
p2 "github.com/elliottech/poseidon_crypto/hash/poseidon2_goldilocks"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
)
|
||||
|
||||
const (
|
||||
templateChangePubKey = "Register Lighter Account\n\npubkey: 0x%s\nnonce: %s\naccount index: %s\napi key index: %s\nOnly sign this message for a trusted client!"
|
||||
)
|
||||
|
||||
func getHex10FromUint64(value uint64) string {
|
||||
v := hexutil.EncodeUint64(value)
|
||||
v = strings.Replace(v, "0x", "", 1)
|
||||
|
||||
// Make sure result has fixed bytes
|
||||
vBytes := []byte(v)
|
||||
if len(vBytes) < 16 {
|
||||
toAppend := make([]byte, 16-len(vBytes))
|
||||
for i := range toAppend {
|
||||
toAppend[i] = 48
|
||||
}
|
||||
vBytes = append(toAppend, vBytes...)
|
||||
}
|
||||
|
||||
return fmt.Sprintf("0x%s", string(vBytes))
|
||||
}
|
||||
|
||||
var _ TxInfo = (*L2ChangePubKeyTxInfo)(nil)
|
||||
|
||||
type L2ChangePubKeyTxInfo struct {
|
||||
AccountIndex int64
|
||||
ApiKeyIndex uint8
|
||||
|
||||
PubKey []byte
|
||||
L1Sig string
|
||||
|
||||
ExpiredAt int64
|
||||
Nonce int64
|
||||
Sig []byte
|
||||
SignedHash string `json:"-"`
|
||||
}
|
||||
|
||||
func (txInfo *L2ChangePubKeyTxInfo) GetTxType() uint8 {
|
||||
return TxTypeL2ChangePubKey
|
||||
}
|
||||
|
||||
func (txInfo *L2ChangePubKeyTxInfo) GetTxInfo() (string, error) {
|
||||
return getTxInfo(txInfo)
|
||||
}
|
||||
|
||||
func (txInfo *L2ChangePubKeyTxInfo) GetTxHash() string {
|
||||
return txInfo.SignedHash
|
||||
}
|
||||
|
||||
func (txInfo *L2ChangePubKeyTxInfo) Validate() error {
|
||||
// AccountIndex
|
||||
if txInfo.AccountIndex < MinAccountIndex {
|
||||
return ErrFromAccountIndexTooLow
|
||||
}
|
||||
if txInfo.AccountIndex > MaxAccountIndex {
|
||||
return ErrFromAccountIndexTooHigh
|
||||
}
|
||||
|
||||
// ApiKeyIndex
|
||||
if txInfo.ApiKeyIndex < MinApiKeyIndex {
|
||||
return ErrApiKeyIndexTooLow
|
||||
}
|
||||
|
||||
if txInfo.ApiKeyIndex > MaxApiKeyIndex {
|
||||
return ErrApiKeyIndexTooHigh
|
||||
}
|
||||
|
||||
if txInfo.Nonce < MinNonce {
|
||||
return ErrNonceTooLow
|
||||
}
|
||||
|
||||
if txInfo.ExpiredAt < 0 || txInfo.ExpiredAt > MaxTimestamp {
|
||||
return ErrExpiredAtInvalid
|
||||
}
|
||||
|
||||
if !IsValidPubKey(txInfo.PubKey) {
|
||||
return ErrPubKeyInvalid
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (txInfo *L2ChangePubKeyTxInfo) GetL1SignatureBody() string {
|
||||
signatureBody := fmt.Sprintf(templateChangePubKey,
|
||||
common.Bytes2Hex(txInfo.PubKey),
|
||||
getHex10FromUint64(uint64(txInfo.Nonce)),
|
||||
getHex10FromUint64(uint64(txInfo.AccountIndex)),
|
||||
getHex10FromUint64(uint64(txInfo.ApiKeyIndex)),
|
||||
)
|
||||
return signatureBody
|
||||
}
|
||||
|
||||
func (txInfo *L2ChangePubKeyTxInfo) Hash(lighterChainId uint32, extra ...g.Element) (msgHash []byte, err error) {
|
||||
elems := make([]g.Element, 0, 11)
|
||||
|
||||
elems = append(elems, g.FromUint32(lighterChainId))
|
||||
elems = append(elems, g.FromUint32(TxTypeL2ChangePubKey))
|
||||
elems = append(elems, g.FromInt64(txInfo.Nonce))
|
||||
elems = append(elems, g.FromInt64(txInfo.ExpiredAt))
|
||||
elems = append(elems, g.FromInt64(txInfo.AccountIndex))
|
||||
elems = append(elems, g.FromUint32(uint32(txInfo.ApiKeyIndex)))
|
||||
|
||||
pubKeyFieldElems, err := g.ArrayFromCanonicalLittleEndianBytes(txInfo.PubKey)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to convert bytes to field element. bytes: %v, error: %w", txInfo.PubKey, err)
|
||||
}
|
||||
elems = append(elems, pubKeyFieldElems...)
|
||||
|
||||
return p2.HashToQuinticExtension(elems).ToLittleEndianBytes(), nil
|
||||
}
|
||||
@@ -1,175 +0,0 @@
|
||||
package txtypes
|
||||
|
||||
import (
|
||||
"math"
|
||||
|
||||
curve "github.com/elliottech/poseidon_crypto/curve/ecgfp5"
|
||||
schnorr "github.com/elliottech/poseidon_crypto/signature/schnorr"
|
||||
)
|
||||
|
||||
type (
|
||||
Signature = schnorr.Signature
|
||||
PrivateKey = curve.ECgFp5Scalar
|
||||
)
|
||||
|
||||
const (
|
||||
NilApiKeyIndex = MaxApiKeyIndex + 1
|
||||
)
|
||||
|
||||
const (
|
||||
TxTypeL2ChangePubKey = 8
|
||||
TxTypeL2CreateSubAccount = 9
|
||||
TxTypeL2CreatePublicPool = 10
|
||||
TxTypeL2UpdatePublicPool = 11
|
||||
TxTypeL2Transfer = 12
|
||||
TxTypeL2Withdraw = 13
|
||||
TxTypeL2CreateOrder = 14
|
||||
TxTypeL2CancelOrder = 15
|
||||
TxTypeL2CancelAllOrders = 16
|
||||
TxTypeL2ModifyOrder = 17
|
||||
TxTypeL2MintShares = 18
|
||||
TxTypeL2BurnShares = 19
|
||||
TxTypeL2UpdateLeverage = 20
|
||||
|
||||
TxTypeInternalClaimOrder = 21
|
||||
TxTypeInternalCancelOrder = 22
|
||||
TxTypeInternalDeleverage = 23
|
||||
TxTypeInternalExitPosition = 24
|
||||
TxTypeInternalCancelAllOrders = 25
|
||||
TxTypeInternalLiquidatePosition = 26
|
||||
TxTypeInternalCreateOrder = 27
|
||||
|
||||
TxTypeL2CreateGroupedOrders = 28
|
||||
TxTypeL2UpdateMargin = 29
|
||||
)
|
||||
|
||||
// Order Type
|
||||
const (
|
||||
// User set order types
|
||||
LimitOrder = iota
|
||||
MarketOrder = 1
|
||||
StopLossOrder = 2
|
||||
StopLossLimitOrder = 3
|
||||
TakeProfitOrder = 4
|
||||
TakeProfitLimitOrder = 5
|
||||
TWAPOrder = 6
|
||||
|
||||
// Internal order types
|
||||
TWAPSubOrder = 7
|
||||
LiquidationOrder = 8
|
||||
|
||||
ApiMaxOrderType = TWAPOrder
|
||||
)
|
||||
|
||||
// Order Time-In-Force
|
||||
const (
|
||||
ImmediateOrCancel = iota
|
||||
GoodTillTime = 1
|
||||
PostOnly = 2
|
||||
)
|
||||
|
||||
// Grouping Type
|
||||
const (
|
||||
GroupingType = 0
|
||||
GroupingType_OneTriggersTheOther = 1
|
||||
GroupingType_OneCancelsTheOther = 2
|
||||
GroupingType_OneTriggersAOneCancelsTheOther = 3
|
||||
)
|
||||
|
||||
// Cancel All Orders Time-In-Force
|
||||
const (
|
||||
ImmediateCancelAll = iota
|
||||
ScheduledCancelAll = 1
|
||||
AbortScheduledCancelAll = 2
|
||||
)
|
||||
|
||||
const (
|
||||
HashLength int = 32
|
||||
|
||||
OneUSDC = 1000000
|
||||
|
||||
FeeTick int64 = 1_000_000
|
||||
MarginFractionTick int64 = 10_000
|
||||
ShareTick int64 = 10_000
|
||||
|
||||
MinAccountIndex int64 = 0
|
||||
MaxAccountIndex int64 = 281474976710654 // (1 << 48) - 2
|
||||
MinApiKeyIndex uint8 = 0
|
||||
MaxApiKeyIndex uint8 = 254 // (1 << 8) - 2
|
||||
MaxMasterAccountIndex int64 = 140737488355327 // (1 << 47) - 1
|
||||
|
||||
MinMarketIndex uint8 = 0
|
||||
MaxMarketIndex uint8 = 254 // (1 << 8) - 2
|
||||
|
||||
MaxInvestedPublicPoolCount int64 = 16
|
||||
InitialPoolShareValue int64 = 1_000 // 0.001 USDC
|
||||
MinInitialTotalShares int64 = 1_000 * (OneUSDC / InitialPoolShareValue) // 1,000 USDC worth of shares
|
||||
MaxInitialTotalShares int64 = 1_000_000_000 * (OneUSDC / InitialPoolShareValue) // 1,000,000,000 USDC worth of shares
|
||||
MaxPoolShares int64 = (1 << 60) - 1
|
||||
MaxBurntShareUSDCValue int64 = (1 << 60) - 1
|
||||
|
||||
MaxPoolEntryUSDC = (1 << 56) - 1 // 2^56 - 1 max USDC to invest in a pool
|
||||
MinPoolSharesToMintOrBurn int64 = 1
|
||||
MaxPoolSharesToMintOrBurn int64 = (1 << 60) - 1
|
||||
|
||||
MinNonce int64 = 0
|
||||
|
||||
MinOrderNonce int64 = 0
|
||||
MaxOrderNonce int64 = (1 << 48) - 1
|
||||
|
||||
NilClientOrderIndex int64 = 0
|
||||
NilOrderIndex int64 = 0
|
||||
|
||||
MinClientOrderIndex int64 = 1
|
||||
MaxClientOrderIndex int64 = (1 << 48) - 1
|
||||
|
||||
MinOrderIndex int64 = MaxClientOrderIndex + 1
|
||||
MaxOrderIndex int64 = (1 << 56) - 1
|
||||
|
||||
MinOrderBaseAmount int64 = 1
|
||||
MaxOrderBaseAmount int64 = (1 << 48) - 1
|
||||
NilOrderBaseAmount int64 = 0
|
||||
|
||||
NilOrderPrice uint32 = 0
|
||||
MinOrderPrice uint32 = 1
|
||||
MaxOrderPrice uint32 = (1 << 32) - 1
|
||||
|
||||
MinOrderCancelAllPeriod int64 = 1000 * 60 * 5 // 5 minutes
|
||||
MaxOrderCancelAllPeriod int64 = 1000 * 60 * 60 * 24 * 15 // 15 days
|
||||
|
||||
NilOrderExpiry int64 = 0
|
||||
MinOrderExpiry int64 = 1
|
||||
MaxOrderExpiry int64 = math.MaxInt64
|
||||
|
||||
MinOrderExpiryPeriod int64 = 1000 * 60 * 5 // 5 minutes
|
||||
MaxOrderExpiryPeriod int64 = 1000 * 60 * 60 * 24 * 30 // 30 days
|
||||
|
||||
NilOrderTriggerPrice uint32 = 0
|
||||
MinOrderTriggerPrice uint32 = 1
|
||||
MaxOrderTriggerPrice uint32 = (1 << 32) - 1
|
||||
|
||||
MaxGroupedOrderCount int64 = 3
|
||||
|
||||
MaxTimestamp = (1 << 48) - 1
|
||||
)
|
||||
|
||||
const (
|
||||
MaxExchangeUSDC = (1 << 60) - 1
|
||||
|
||||
MinTransferAmount int64 = 1
|
||||
MaxTransferAmount int64 = MaxExchangeUSDC
|
||||
|
||||
MinWithdrawalAmount uint64 = 1
|
||||
MaxWithdrawalAmount uint64 = MaxExchangeUSDC
|
||||
)
|
||||
|
||||
// Margin Modes
|
||||
const (
|
||||
CrossMargin = iota
|
||||
IsolatedMargin = 1
|
||||
)
|
||||
|
||||
const (
|
||||
RemoveFromIsolatedMargin = 0
|
||||
AddToIsolatedMargin = 1
|
||||
)
|
||||
@@ -1,336 +0,0 @@
|
||||
package txtypes
|
||||
|
||||
import (
|
||||
g "github.com/elliottech/poseidon_crypto/field/goldilocks"
|
||||
p2 "github.com/elliottech/poseidon_crypto/hash/poseidon2_goldilocks"
|
||||
)
|
||||
|
||||
var _ TxInfo = (*L2CreateGroupedOrdersTxInfo)(nil)
|
||||
|
||||
// !!! Ensure that if primary order is reduce only, all child orders are also reduce only
|
||||
// !!! Otherwise CancelPositionTiedAccountOrders flow breaks
|
||||
type L2CreateGroupedOrdersTxInfo struct {
|
||||
AccountIndex int64
|
||||
ApiKeyIndex uint8
|
||||
GroupingType uint8
|
||||
|
||||
Orders []*OrderInfo
|
||||
|
||||
ExpiredAt int64
|
||||
Nonce int64
|
||||
Sig []byte
|
||||
SignedHash string `json:"-"`
|
||||
}
|
||||
|
||||
func (txInfo *L2CreateGroupedOrdersTxInfo) GetTxType() uint8 {
|
||||
return TxTypeL2CreateGroupedOrders
|
||||
}
|
||||
|
||||
func (txInfo *L2CreateGroupedOrdersTxInfo) GetTxInfo() (string, error) {
|
||||
return getTxInfo(txInfo)
|
||||
}
|
||||
|
||||
func (txInfo *L2CreateGroupedOrdersTxInfo) GetTxHash() string {
|
||||
return txInfo.SignedHash
|
||||
}
|
||||
|
||||
func (txInfo *L2CreateGroupedOrdersTxInfo) Validate() error {
|
||||
// AccountIndex
|
||||
if txInfo.AccountIndex < MinAccountIndex {
|
||||
return ErrAccountIndexTooLow
|
||||
}
|
||||
if txInfo.AccountIndex > MaxAccountIndex {
|
||||
return ErrAccountIndexTooHigh
|
||||
}
|
||||
// ApiKeyIndex
|
||||
if txInfo.ApiKeyIndex < MinApiKeyIndex {
|
||||
return ErrApiKeyIndexTooLow
|
||||
}
|
||||
if txInfo.ApiKeyIndex > MaxApiKeyIndex {
|
||||
return ErrApiKeyIndexTooHigh
|
||||
}
|
||||
|
||||
if len(txInfo.Orders) == 0 || len(txInfo.Orders) > int(MaxGroupedOrderCount) {
|
||||
return ErrOrderGroupSizeInvalid
|
||||
}
|
||||
|
||||
// MarketIndex for first order
|
||||
if txInfo.Orders[0].MarketIndex < MinMarketIndex {
|
||||
return ErrMarketIndexTooLow
|
||||
}
|
||||
if txInfo.Orders[0].MarketIndex > MaxMarketIndex {
|
||||
return ErrMarketIndexTooHigh
|
||||
}
|
||||
|
||||
// Perform range checks for all orders
|
||||
for _, order := range txInfo.Orders {
|
||||
// MarketIndex
|
||||
if order.MarketIndex != txInfo.Orders[0].MarketIndex {
|
||||
return ErrMarketIndexMismatch
|
||||
}
|
||||
|
||||
// ClientOrderIndex
|
||||
if order.ClientOrderIndex != NilClientOrderIndex {
|
||||
return ErrClientOrderIndexNotNil
|
||||
}
|
||||
|
||||
// BaseAmount
|
||||
if order.ReduceOnly != 1 && order.BaseAmount == NilOrderBaseAmount {
|
||||
return ErrBaseAmountTooLow
|
||||
}
|
||||
if order.BaseAmount != NilOrderBaseAmount && order.BaseAmount < MinOrderBaseAmount {
|
||||
return ErrBaseAmountTooLow
|
||||
}
|
||||
if order.BaseAmount > MaxOrderBaseAmount {
|
||||
return ErrBaseAmountTooHigh
|
||||
}
|
||||
|
||||
// Price
|
||||
if order.Price < MinOrderPrice {
|
||||
return ErrPriceTooLow
|
||||
}
|
||||
if order.Price > MaxOrderPrice {
|
||||
return ErrPriceTooHigh
|
||||
}
|
||||
|
||||
// IsAsk
|
||||
if order.IsAsk != 0 && order.IsAsk != 1 {
|
||||
return ErrIsAskInvalid
|
||||
}
|
||||
|
||||
// TimeInForce
|
||||
if order.TimeInForce != ImmediateOrCancel && order.TimeInForce != GoodTillTime && order.TimeInForce != PostOnly {
|
||||
return ErrOrderTimeInForceInvalid
|
||||
}
|
||||
|
||||
// ReduceOnly
|
||||
if order.ReduceOnly != 0 && order.ReduceOnly != 1 {
|
||||
return ErrOrderReduceOnlyInvalid
|
||||
}
|
||||
|
||||
// OrderExpiry
|
||||
if (order.OrderExpiry < MinOrderExpiry || order.OrderExpiry > MaxOrderExpiry) && order.OrderExpiry != NilOrderExpiry {
|
||||
return ErrOrderExpiryInvalid
|
||||
}
|
||||
|
||||
// TriggerPrice
|
||||
if (order.TriggerPrice < MinOrderTriggerPrice || order.TriggerPrice > MaxOrderTriggerPrice) && order.TriggerPrice != NilOrderTriggerPrice {
|
||||
return ErrOrderTriggerPriceInvalid
|
||||
}
|
||||
}
|
||||
|
||||
// Nonce
|
||||
if txInfo.Nonce < MinNonce {
|
||||
return ErrNonceTooLow
|
||||
}
|
||||
|
||||
if txInfo.ExpiredAt < 0 || txInfo.ExpiredAt > MaxTimestamp {
|
||||
return ErrExpiredAtInvalid
|
||||
}
|
||||
|
||||
switch txInfo.GroupingType {
|
||||
case GroupingType_OneCancelsTheOther:
|
||||
return txInfo.ValidateOCO()
|
||||
case GroupingType_OneTriggersTheOther:
|
||||
return txInfo.ValidateOTO()
|
||||
case GroupingType_OneTriggersAOneCancelsTheOther:
|
||||
return txInfo.ValidateOTOCO()
|
||||
default:
|
||||
return ErrGroupingTypeInvalid
|
||||
}
|
||||
}
|
||||
|
||||
func (txInfo *L2CreateGroupedOrdersTxInfo) ValidateParentOrder(order *OrderInfo) error {
|
||||
switch order.Type {
|
||||
case MarketOrder:
|
||||
if order.TimeInForce != ImmediateOrCancel {
|
||||
return ErrOrderTimeInForceInvalid
|
||||
} else if order.OrderExpiry != NilOrderExpiry {
|
||||
return ErrOrderExpiryInvalid
|
||||
} else if order.TriggerPrice != NilOrderTriggerPrice {
|
||||
return ErrOrderTriggerPriceInvalid
|
||||
}
|
||||
case LimitOrder:
|
||||
if order.TriggerPrice != NilOrderTriggerPrice {
|
||||
return ErrOrderTriggerPriceInvalid
|
||||
} else if order.TimeInForce == ImmediateOrCancel && order.OrderExpiry != NilOrderExpiry {
|
||||
return ErrOrderExpiryInvalid
|
||||
} else if order.TimeInForce != ImmediateOrCancel && order.OrderExpiry == NilOrderExpiry {
|
||||
return ErrOrderExpiryInvalid
|
||||
}
|
||||
default:
|
||||
return ErrOrderTypeInvalid
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (txInfo *L2CreateGroupedOrdersTxInfo) ValidateChildOrder(order *OrderInfo) error {
|
||||
switch order.Type {
|
||||
case StopLossOrder, TakeProfitOrder:
|
||||
if order.TimeInForce != ImmediateOrCancel {
|
||||
return ErrOrderTimeInForceInvalid
|
||||
} else if order.TriggerPrice == NilOrderTriggerPrice {
|
||||
return ErrOrderTriggerPriceInvalid
|
||||
} else if order.OrderExpiry == NilOrderExpiry {
|
||||
return ErrOrderExpiryInvalid
|
||||
}
|
||||
case StopLossLimitOrder, TakeProfitLimitOrder:
|
||||
if order.TriggerPrice == NilOrderTriggerPrice {
|
||||
return ErrOrderTriggerPriceInvalid
|
||||
} else if order.OrderExpiry == NilOrderExpiry {
|
||||
return ErrOrderExpiryInvalid
|
||||
}
|
||||
default:
|
||||
return ErrOrderTypeInvalid
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (txInfo *L2CreateGroupedOrdersTxInfo) ValidateSiblingOrders(orders []*OrderInfo) error {
|
||||
if len(orders) != 2 {
|
||||
return ErrOrderGroupSizeInvalid
|
||||
}
|
||||
slFlag := false
|
||||
tpFlag := false
|
||||
for _, order := range orders {
|
||||
err := txInfo.ValidateChildOrder(order)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if order.Type == StopLossOrder || order.Type == StopLossLimitOrder {
|
||||
slFlag = true
|
||||
} else if order.Type == TakeProfitOrder || order.Type == TakeProfitLimitOrder {
|
||||
tpFlag = true
|
||||
}
|
||||
}
|
||||
if !slFlag || !tpFlag {
|
||||
return ErrOrderTypeInvalid
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (txInfo *L2CreateGroupedOrdersTxInfo) ValidateOCO() error {
|
||||
if len(txInfo.Orders) != 2 {
|
||||
return ErrOrderGroupSizeInvalid
|
||||
}
|
||||
|
||||
// Ensure both orders base sizes are same
|
||||
if txInfo.Orders[0].BaseAmount != txInfo.Orders[1].BaseAmount {
|
||||
return ErrBaseAmountsNotEqual
|
||||
}
|
||||
|
||||
// Orders should be in the same direction
|
||||
if txInfo.Orders[0].IsAsk != txInfo.Orders[1].IsAsk {
|
||||
return ErrIsAskInvalid
|
||||
}
|
||||
|
||||
// Ensure both orders are reduce only
|
||||
if txInfo.Orders[0].ReduceOnly != 1 || txInfo.Orders[1].ReduceOnly != 1 {
|
||||
return ErrOrderReduceOnlyInvalid
|
||||
}
|
||||
|
||||
// Ensure both orders have the same non-nil expiry
|
||||
if txInfo.Orders[0].OrderExpiry != txInfo.Orders[1].OrderExpiry {
|
||||
return ErrOrderExpiryInvalid
|
||||
}
|
||||
|
||||
return txInfo.ValidateSiblingOrders(txInfo.Orders)
|
||||
}
|
||||
|
||||
func (txInfo *L2CreateGroupedOrdersTxInfo) ValidateOTO() error {
|
||||
if len(txInfo.Orders) != 2 {
|
||||
return ErrOrderGroupSizeInvalid
|
||||
}
|
||||
|
||||
// Ensure child order base size is 0
|
||||
if txInfo.Orders[1].BaseAmount != NilOrderBaseAmount {
|
||||
return ErrBaseAmountNotNil
|
||||
}
|
||||
|
||||
// Orders should be in the opposite direction
|
||||
if txInfo.Orders[0].IsAsk == txInfo.Orders[1].IsAsk {
|
||||
return ErrIsAskInvalid
|
||||
}
|
||||
|
||||
// Ensure if expiries are not nil, they are the same
|
||||
if txInfo.Orders[0].OrderExpiry != NilOrderExpiry &&
|
||||
txInfo.Orders[0].OrderExpiry != txInfo.Orders[1].OrderExpiry {
|
||||
return ErrOrderExpiryInvalid
|
||||
}
|
||||
|
||||
err := txInfo.ValidateParentOrder(txInfo.Orders[0])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return txInfo.ValidateChildOrder(txInfo.Orders[1])
|
||||
}
|
||||
|
||||
func (txInfo *L2CreateGroupedOrdersTxInfo) ValidateOTOCO() error {
|
||||
if len(txInfo.Orders) != 3 {
|
||||
return ErrOrderGroupSizeInvalid
|
||||
}
|
||||
|
||||
// Ensure child orders base size is 0
|
||||
if txInfo.Orders[1].BaseAmount != NilOrderBaseAmount || txInfo.Orders[2].BaseAmount != NilOrderBaseAmount {
|
||||
return ErrBaseAmountNotNil
|
||||
}
|
||||
|
||||
// Primary and child orders should be in the oppsite direction
|
||||
if txInfo.Orders[0].IsAsk == txInfo.Orders[1].IsAsk || txInfo.Orders[0].IsAsk == txInfo.Orders[2].IsAsk {
|
||||
return ErrIsAskInvalid
|
||||
}
|
||||
|
||||
// Ensure child orders has the same expiry
|
||||
if txInfo.Orders[1].OrderExpiry != txInfo.Orders[2].OrderExpiry {
|
||||
return ErrOrderExpiryInvalid
|
||||
}
|
||||
|
||||
// Ensure if expiries are not nil, they are the same
|
||||
if txInfo.Orders[0].OrderExpiry != NilOrderExpiry &&
|
||||
txInfo.Orders[0].OrderExpiry != txInfo.Orders[1].OrderExpiry {
|
||||
return ErrOrderExpiryInvalid
|
||||
}
|
||||
|
||||
err := txInfo.ValidateParentOrder(txInfo.Orders[0])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return txInfo.ValidateSiblingOrders(txInfo.Orders[1:])
|
||||
}
|
||||
|
||||
func (txInfo *L2CreateGroupedOrdersTxInfo) Hash(lighterChainId uint32, extra ...g.Element) (msgHash []byte, err error) {
|
||||
elems := make([]g.Element, 0, 11)
|
||||
elems = append(elems, g.FromUint32(lighterChainId))
|
||||
elems = append(elems, g.FromUint32(TxTypeL2CreateGroupedOrders))
|
||||
elems = append(elems, g.FromInt64(txInfo.Nonce))
|
||||
elems = append(elems, g.FromInt64(txInfo.ExpiredAt))
|
||||
|
||||
elems = append(elems, g.FromInt64(txInfo.AccountIndex))
|
||||
elems = append(elems, g.FromUint32(uint32(txInfo.ApiKeyIndex)))
|
||||
elems = append(elems, g.FromUint32(uint32(txInfo.GroupingType)))
|
||||
|
||||
aggregatedOrderHash := p2.EmptyHashOut()
|
||||
for index, order := range txInfo.Orders {
|
||||
orderHash := p2.HashNoPad([]g.Element{
|
||||
g.FromUint32(uint32(order.MarketIndex)),
|
||||
g.FromInt64(order.ClientOrderIndex),
|
||||
g.FromInt64(order.BaseAmount),
|
||||
g.FromUint32(order.Price),
|
||||
g.FromUint32(uint32(order.IsAsk)),
|
||||
g.FromUint32(uint32(order.Type)),
|
||||
g.FromUint32(uint32(order.TimeInForce)),
|
||||
g.FromUint32(uint32(order.ReduceOnly)),
|
||||
g.FromUint32(order.TriggerPrice),
|
||||
g.FromInt64(order.OrderExpiry),
|
||||
})
|
||||
if index == 0 {
|
||||
aggregatedOrderHash = orderHash
|
||||
} else {
|
||||
aggregatedOrderHash = p2.HashNToOne([]p2.HashOut{aggregatedOrderHash, orderHash})
|
||||
}
|
||||
}
|
||||
elems = append(elems, aggregatedOrderHash[:]...)
|
||||
|
||||
return p2.HashToQuinticExtension(elems).ToLittleEndianBytes(), nil
|
||||
}
|
||||
@@ -1,186 +0,0 @@
|
||||
package txtypes
|
||||
|
||||
import (
|
||||
g "github.com/elliottech/poseidon_crypto/field/goldilocks"
|
||||
p2 "github.com/elliottech/poseidon_crypto/hash/poseidon2_goldilocks"
|
||||
)
|
||||
|
||||
var _ TxInfo = (*L2CreateOrderTxInfo)(nil)
|
||||
|
||||
type L2CreateOrderTxInfo struct {
|
||||
AccountIndex int64
|
||||
ApiKeyIndex uint8
|
||||
|
||||
*OrderInfo
|
||||
|
||||
ExpiredAt int64
|
||||
Nonce int64
|
||||
Sig []byte
|
||||
SignedHash string `json:"-"`
|
||||
}
|
||||
|
||||
func (txInfo *L2CreateOrderTxInfo) GetTxType() uint8 {
|
||||
return TxTypeL2CreateOrder
|
||||
}
|
||||
|
||||
func (txInfo *L2CreateOrderTxInfo) GetTxInfo() (string, error) {
|
||||
return getTxInfo(txInfo)
|
||||
}
|
||||
|
||||
func (txInfo *L2CreateOrderTxInfo) GetTxHash() string {
|
||||
return txInfo.SignedHash
|
||||
}
|
||||
|
||||
func (txInfo *L2CreateOrderTxInfo) Validate() error {
|
||||
// AccountIndex
|
||||
if txInfo.AccountIndex < MinAccountIndex {
|
||||
return ErrAccountIndexTooLow
|
||||
}
|
||||
if txInfo.AccountIndex > MaxAccountIndex {
|
||||
return ErrAccountIndexTooHigh
|
||||
}
|
||||
// ApiKeyIndex
|
||||
if txInfo.ApiKeyIndex < MinApiKeyIndex {
|
||||
return ErrApiKeyIndexTooLow
|
||||
}
|
||||
if txInfo.ApiKeyIndex > MaxApiKeyIndex {
|
||||
return ErrApiKeyIndexTooHigh
|
||||
}
|
||||
|
||||
// MarketIndex
|
||||
if txInfo.MarketIndex < MinMarketIndex {
|
||||
return ErrMarketIndexTooLow
|
||||
}
|
||||
if txInfo.MarketIndex > MaxMarketIndex {
|
||||
return ErrMarketIndexTooHigh
|
||||
}
|
||||
|
||||
// ClientOrderIndex
|
||||
if txInfo.ClientOrderIndex != NilClientOrderIndex {
|
||||
if txInfo.ClientOrderIndex < MinClientOrderIndex {
|
||||
return ErrClientOrderIndexTooLow
|
||||
}
|
||||
if txInfo.ClientOrderIndex > MaxClientOrderIndex {
|
||||
return ErrClientOrderIndexTooHigh
|
||||
}
|
||||
}
|
||||
|
||||
// BaseAmount
|
||||
if txInfo.ReduceOnly != 1 && txInfo.BaseAmount == NilOrderBaseAmount {
|
||||
return ErrBaseAmountTooLow
|
||||
}
|
||||
if txInfo.BaseAmount != NilOrderBaseAmount && txInfo.BaseAmount < MinOrderBaseAmount {
|
||||
return ErrBaseAmountTooLow
|
||||
}
|
||||
if txInfo.BaseAmount > MaxOrderBaseAmount {
|
||||
return ErrBaseAmountTooHigh
|
||||
}
|
||||
|
||||
// Price
|
||||
if txInfo.Price < MinOrderPrice {
|
||||
return ErrPriceTooLow
|
||||
}
|
||||
if txInfo.Price > MaxOrderPrice {
|
||||
return ErrPriceTooHigh
|
||||
}
|
||||
|
||||
// IsAsk
|
||||
if txInfo.IsAsk != 0 && txInfo.IsAsk != 1 {
|
||||
return ErrIsAskInvalid
|
||||
}
|
||||
|
||||
if txInfo.TimeInForce != ImmediateOrCancel && txInfo.TimeInForce != GoodTillTime && txInfo.TimeInForce != PostOnly {
|
||||
return ErrOrderTimeInForceInvalid
|
||||
}
|
||||
|
||||
if txInfo.ReduceOnly != 0 && txInfo.ReduceOnly != 1 {
|
||||
return ErrOrderReduceOnlyInvalid
|
||||
}
|
||||
|
||||
if (txInfo.OrderExpiry < MinOrderExpiry || txInfo.OrderExpiry > MaxOrderExpiry) && txInfo.OrderExpiry != NilOrderExpiry {
|
||||
return ErrOrderExpiryInvalid
|
||||
}
|
||||
|
||||
switch txInfo.Type {
|
||||
case MarketOrder:
|
||||
if txInfo.TimeInForce != ImmediateOrCancel {
|
||||
return ErrOrderTimeInForceInvalid
|
||||
} else if txInfo.OrderExpiry != NilOrderExpiry {
|
||||
return ErrOrderExpiryInvalid
|
||||
} else if txInfo.TriggerPrice != NilOrderTriggerPrice {
|
||||
return ErrOrderTriggerPriceInvalid
|
||||
}
|
||||
case LimitOrder:
|
||||
if txInfo.TriggerPrice != NilOrderTriggerPrice {
|
||||
return ErrOrderTriggerPriceInvalid
|
||||
} else if txInfo.TimeInForce == ImmediateOrCancel && txInfo.OrderExpiry != NilOrderExpiry {
|
||||
return ErrOrderExpiryInvalid
|
||||
} else if txInfo.TimeInForce != ImmediateOrCancel && txInfo.OrderExpiry == NilOrderExpiry {
|
||||
return ErrOrderExpiryInvalid
|
||||
}
|
||||
case StopLossOrder, TakeProfitOrder:
|
||||
if txInfo.TimeInForce != ImmediateOrCancel {
|
||||
return ErrOrderTimeInForceInvalid
|
||||
} else if txInfo.TriggerPrice == NilOrderTriggerPrice {
|
||||
return ErrOrderTriggerPriceInvalid
|
||||
} else if txInfo.OrderExpiry == NilOrderExpiry {
|
||||
return ErrOrderExpiryInvalid
|
||||
}
|
||||
case StopLossLimitOrder, TakeProfitLimitOrder:
|
||||
if txInfo.TriggerPrice == NilOrderTriggerPrice {
|
||||
return ErrOrderTriggerPriceInvalid
|
||||
} else if txInfo.OrderExpiry == NilOrderExpiry {
|
||||
return ErrOrderExpiryInvalid
|
||||
}
|
||||
case TWAPOrder:
|
||||
if txInfo.TimeInForce != GoodTillTime {
|
||||
return ErrOrderTimeInForceInvalid
|
||||
} else if txInfo.TriggerPrice != NilOrderTriggerPrice {
|
||||
return ErrOrderTriggerPriceInvalid
|
||||
} else if txInfo.OrderExpiry == NilOrderExpiry {
|
||||
return ErrOrderExpiryInvalid
|
||||
}
|
||||
default:
|
||||
return ErrOrderTypeInvalid
|
||||
}
|
||||
|
||||
// TriggerPrice
|
||||
if (txInfo.TriggerPrice < MinOrderTriggerPrice || txInfo.TriggerPrice > MaxOrderTriggerPrice) && txInfo.TriggerPrice != NilOrderTriggerPrice {
|
||||
return ErrOrderTriggerPriceInvalid
|
||||
}
|
||||
|
||||
// Nonce
|
||||
if txInfo.Nonce < MinNonce {
|
||||
return ErrNonceTooLow
|
||||
}
|
||||
|
||||
if txInfo.ExpiredAt < 0 || txInfo.ExpiredAt > MaxTimestamp {
|
||||
return ErrExpiredAtInvalid
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (txInfo *L2CreateOrderTxInfo) Hash(lighterChainId uint32, extra ...g.Element) (msgHash []byte, err error) {
|
||||
elems := make([]g.Element, 0, 16)
|
||||
|
||||
elems = append(elems, g.FromUint32(lighterChainId))
|
||||
elems = append(elems, g.FromUint32(TxTypeL2CreateOrder))
|
||||
elems = append(elems, g.FromInt64(txInfo.Nonce))
|
||||
elems = append(elems, g.FromInt64(txInfo.ExpiredAt))
|
||||
|
||||
elems = append(elems, g.FromInt64(txInfo.AccountIndex))
|
||||
elems = append(elems, g.FromUint32(uint32(txInfo.ApiKeyIndex)))
|
||||
elems = append(elems, g.FromUint32(uint32(txInfo.MarketIndex)))
|
||||
elems = append(elems, g.FromInt64(txInfo.ClientOrderIndex))
|
||||
elems = append(elems, g.FromInt64(txInfo.BaseAmount))
|
||||
elems = append(elems, g.FromUint32(txInfo.Price))
|
||||
elems = append(elems, g.FromUint32(uint32(txInfo.IsAsk)))
|
||||
elems = append(elems, g.FromUint32(uint32(txInfo.Type)))
|
||||
elems = append(elems, g.FromUint32(uint32(txInfo.TimeInForce)))
|
||||
elems = append(elems, g.FromUint32(uint32(txInfo.ReduceOnly)))
|
||||
elems = append(elems, g.FromUint32(txInfo.TriggerPrice))
|
||||
elems = append(elems, g.FromInt64(txInfo.OrderExpiry))
|
||||
|
||||
return p2.HashToQuinticExtension(elems).ToLittleEndianBytes(), nil
|
||||
}
|
||||
@@ -1,101 +0,0 @@
|
||||
package txtypes
|
||||
|
||||
import (
|
||||
g "github.com/elliottech/poseidon_crypto/field/goldilocks"
|
||||
p2 "github.com/elliottech/poseidon_crypto/hash/poseidon2_goldilocks"
|
||||
)
|
||||
|
||||
var _ TxInfo = (*L2CreatePublicPoolTxInfo)(nil)
|
||||
|
||||
type L2CreatePublicPoolTxInfo struct {
|
||||
AccountIndex int64 // Master account index
|
||||
ApiKeyIndex uint8
|
||||
|
||||
OperatorFee int64
|
||||
InitialTotalShares int64
|
||||
MinOperatorShareRate int64
|
||||
|
||||
ExpiredAt int64
|
||||
Nonce int64
|
||||
Sig []byte
|
||||
SignedHash string `json:"-"`
|
||||
}
|
||||
|
||||
func (txInfo *L2CreatePublicPoolTxInfo) GetTxType() uint8 {
|
||||
return TxTypeL2CreatePublicPool
|
||||
}
|
||||
|
||||
func (txInfo *L2CreatePublicPoolTxInfo) GetTxInfo() (string, error) {
|
||||
return getTxInfo(txInfo)
|
||||
}
|
||||
|
||||
func (txInfo *L2CreatePublicPoolTxInfo) GetTxHash() string {
|
||||
return txInfo.SignedHash
|
||||
}
|
||||
|
||||
func (txInfo *L2CreatePublicPoolTxInfo) Validate() error {
|
||||
// AccountIndex
|
||||
if txInfo.AccountIndex < MinAccountIndex {
|
||||
return ErrFromAccountIndexTooLow
|
||||
}
|
||||
if txInfo.AccountIndex > MaxMasterAccountIndex {
|
||||
return ErrFromAccountIndexTooHigh
|
||||
}
|
||||
|
||||
// ApiKeyIndex
|
||||
if txInfo.ApiKeyIndex < MinApiKeyIndex {
|
||||
return ErrApiKeyIndexTooLow
|
||||
}
|
||||
if txInfo.ApiKeyIndex > MaxApiKeyIndex {
|
||||
return ErrApiKeyIndexTooHigh
|
||||
}
|
||||
|
||||
// OperatorFee
|
||||
if txInfo.OperatorFee < 0 || txInfo.OperatorFee > FeeTick {
|
||||
return ErrInvalidPoolOperatorFee
|
||||
}
|
||||
|
||||
// InitialTotalShares
|
||||
if txInfo.InitialTotalShares <= 0 {
|
||||
return ErrPoolInitialTotalSharesTooLow
|
||||
}
|
||||
if txInfo.InitialTotalShares > MaxInitialTotalShares {
|
||||
return ErrPoolInitialTotalSharesTooHigh
|
||||
}
|
||||
|
||||
// MinOperatorShareRate
|
||||
if txInfo.MinOperatorShareRate < 0 {
|
||||
return ErrPoolMinOperatorShareRateTooLow
|
||||
}
|
||||
if txInfo.MinOperatorShareRate > ShareTick {
|
||||
return ErrPoolMinOperatorShareRateTooHigh
|
||||
}
|
||||
|
||||
// Nonce
|
||||
if txInfo.Nonce < MinNonce {
|
||||
return ErrNonceTooLow
|
||||
}
|
||||
|
||||
if txInfo.ExpiredAt < 0 || txInfo.ExpiredAt > MaxTimestamp {
|
||||
return ErrExpiredAtInvalid
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (txInfo *L2CreatePublicPoolTxInfo) Hash(lighterChainId uint32, extra ...g.Element) (msgHash []byte, err error) {
|
||||
elems := make([]g.Element, 0, 9)
|
||||
|
||||
elems = append(elems, g.FromUint32(lighterChainId))
|
||||
elems = append(elems, g.FromUint32(TxTypeL2CreatePublicPool))
|
||||
elems = append(elems, g.FromInt64(txInfo.Nonce))
|
||||
elems = append(elems, g.FromInt64(txInfo.ExpiredAt))
|
||||
|
||||
elems = append(elems, g.FromInt64(txInfo.AccountIndex))
|
||||
elems = append(elems, g.FromUint32(uint32(txInfo.ApiKeyIndex)))
|
||||
elems = append(elems, g.FromInt64(txInfo.OperatorFee))
|
||||
elems = append(elems, g.FromInt64(txInfo.InitialTotalShares))
|
||||
elems = append(elems, g.FromInt64(txInfo.MinOperatorShareRate))
|
||||
|
||||
return p2.HashToQuinticExtension(elems).ToLittleEndianBytes(), nil
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
package txtypes
|
||||
|
||||
import (
|
||||
g "github.com/elliottech/poseidon_crypto/field/goldilocks"
|
||||
p2 "github.com/elliottech/poseidon_crypto/hash/poseidon2_goldilocks"
|
||||
)
|
||||
|
||||
var _ TxInfo = (*L2CreateSubAccountTxInfo)(nil)
|
||||
|
||||
type L2CreateSubAccountTxInfo struct {
|
||||
AccountIndex int64 // Master account index
|
||||
ApiKeyIndex uint8
|
||||
|
||||
ExpiredAt int64
|
||||
Nonce int64
|
||||
Sig []byte
|
||||
SignedHash string `json:"-"`
|
||||
}
|
||||
|
||||
func (txInfo *L2CreateSubAccountTxInfo) GetTxType() uint8 {
|
||||
return TxTypeL2CreateSubAccount
|
||||
}
|
||||
|
||||
func (txInfo *L2CreateSubAccountTxInfo) GetTxInfo() (string, error) {
|
||||
return getTxInfo(txInfo)
|
||||
}
|
||||
|
||||
func (txInfo *L2CreateSubAccountTxInfo) GetTxHash() string {
|
||||
return txInfo.SignedHash
|
||||
}
|
||||
|
||||
func (txInfo *L2CreateSubAccountTxInfo) Validate() error {
|
||||
// AccountIndex
|
||||
if txInfo.AccountIndex < MinAccountIndex {
|
||||
return ErrFromAccountIndexTooLow
|
||||
}
|
||||
if txInfo.AccountIndex > MaxAccountIndex {
|
||||
return ErrFromAccountIndexTooHigh
|
||||
}
|
||||
|
||||
// ApiKeyIndex
|
||||
if txInfo.ApiKeyIndex < MinApiKeyIndex {
|
||||
return ErrApiKeyIndexTooLow
|
||||
}
|
||||
if txInfo.ApiKeyIndex > MaxApiKeyIndex {
|
||||
return ErrApiKeyIndexTooHigh
|
||||
}
|
||||
|
||||
// Nonce
|
||||
if txInfo.Nonce < MinNonce {
|
||||
return ErrNonceTooLow
|
||||
}
|
||||
|
||||
if txInfo.ExpiredAt < 0 || txInfo.ExpiredAt > MaxTimestamp {
|
||||
return ErrExpiredAtInvalid
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (txInfo *L2CreateSubAccountTxInfo) Hash(lighterChainId uint32, extra ...g.Element) (msgHash []byte, err error) {
|
||||
elems := make([]g.Element, 0, 6)
|
||||
|
||||
elems = append(elems, g.FromUint32(lighterChainId))
|
||||
elems = append(elems, g.FromUint32(TxTypeL2CreateSubAccount))
|
||||
elems = append(elems, g.FromInt64(txInfo.Nonce))
|
||||
elems = append(elems, g.FromInt64(txInfo.ExpiredAt))
|
||||
|
||||
elems = append(elems, g.FromInt64(txInfo.AccountIndex))
|
||||
elems = append(elems, g.FromUint32(uint32(txInfo.ApiKeyIndex)))
|
||||
|
||||
return p2.HashToQuinticExtension(elems).ToLittleEndianBytes(), nil
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
package txtypes
|
||||
|
||||
import "fmt"
|
||||
|
||||
var (
|
||||
ErrAccountIndexTooLow = fmt.Errorf("AccountIndex should not be less than %d", MinAccountIndex)
|
||||
ErrAccountIndexTooHigh = fmt.Errorf("AccountIndex should not be larger than %d", MaxAccountIndex)
|
||||
ErrNonceTooLow = fmt.Errorf("AccountNonce should not be less than %d", MinNonce)
|
||||
ErrInvalidCancelAllTimeInForce = fmt.Errorf("CancelAllTimeInForce is invalid")
|
||||
ErrOrderReduceOnlyInvalid = fmt.Errorf("ReduceOnly is invalid")
|
||||
ErrOrderTriggerPriceInvalid = fmt.Errorf("TriggerPrice is invalid")
|
||||
ErrOrderExpiryInvalid = fmt.Errorf("OrderExpiry is invalid")
|
||||
ErrExpiredAtInvalid = fmt.Errorf("ExpiredAt is invalid")
|
||||
ErrCancelAllTimeIsNotInRange = fmt.Errorf("CancelAllTime should be larger than 0 and not larger than %d", MaxOrderExpiry)
|
||||
ErrCancelAllTimeisNotNill = fmt.Errorf("CancelAllTime should be nil")
|
||||
ErrPubKeyInvalid = fmt.Errorf("PubKey is invalid")
|
||||
ErrToAccountIndexTooLow = fmt.Errorf("ToAccountIndex should not be less than %d", MinAccountIndex)
|
||||
ErrToAccountIndexTooHigh = fmt.Errorf("ToAccountIndex should not be larger than %d", MaxAccountIndex)
|
||||
ErrFromAccountIndexTooLow = fmt.Errorf("FromAccountIndex should not be less than %d", MinAccountIndex)
|
||||
ErrFromAccountIndexTooHigh = fmt.Errorf("FromAccountIndex should not be larger than %d", MaxAccountIndex)
|
||||
ErrApiKeyIndexTooLow = fmt.Errorf("ApiKeyIndex should not be less than %d", MinApiKeyIndex)
|
||||
ErrApiKeyIndexTooHigh = fmt.Errorf("ApiKeyIndex should not be larger than %d", MaxApiKeyIndex)
|
||||
ErrPublicPoolIndexTooLow = fmt.Errorf("PublicPoolIndex should not be less than %d", MinAccountIndex)
|
||||
ErrPublicPoolIndexTooHigh = fmt.Errorf("PublicPoolIndex should not be larger than %d", MaxAccountIndex)
|
||||
ErrInvalidPoolOperatorFee = fmt.Errorf("PoolOperatorFee should be larger than 0 and not larger than %d", FeeTick)
|
||||
ErrInvalidPoolStatus = fmt.Errorf("PoolStatus should be either 0 or 1")
|
||||
ErrPoolInitialTotalSharesTooLow = fmt.Errorf("PoolInitialTotalShares should be larger than %d", MinInitialTotalShares)
|
||||
ErrPoolInitialTotalSharesTooHigh = fmt.Errorf("PoolInitialTotalShares should not be larger than %d", MaxInitialTotalShares)
|
||||
ErrPoolMinOperatorShareRateTooLow = fmt.Errorf("PoolMinOperatorShareRate should be larger than 0")
|
||||
ErrPoolMinOperatorShareRateTooHigh = fmt.Errorf("PoolMinOperatorShareRate should not be larger than %d", ShareTick)
|
||||
ErrPoolMintShareAmountTooLow = fmt.Errorf("PoolMintShareAmount should be larger than %d", MinPoolSharesToMintOrBurn)
|
||||
ErrPoolMintShareAmountTooHigh = fmt.Errorf("PoolMintShareAmount should not be larger than %d", MaxPoolSharesToMintOrBurn)
|
||||
ErrPoolBurnShareAmountTooLow = fmt.Errorf("PoolBurnShareAmount should be larger than %d", MinPoolSharesToMintOrBurn)
|
||||
ErrPoolBurnShareAmountTooHigh = fmt.Errorf("PoolBurnShareAmount should not be larger than %d", MaxPoolSharesToMintOrBurn)
|
||||
ErrWithdrawalAmountTooLow = fmt.Errorf("WithdrawalAmount should be larger than %d", MinWithdrawalAmount)
|
||||
ErrWithdrawalAmountTooHigh = fmt.Errorf("WithdrawalAmount should not be larger than %d", MaxWithdrawalAmount)
|
||||
ErrTransferAmountTooLow = fmt.Errorf("TransferAmount should be larger than %d", MinTransferAmount)
|
||||
ErrTransferAmountTooHigh = fmt.Errorf("TransferAmount should not be larger than %d", MaxTransferAmount)
|
||||
ErrMarketIndexTooLow = fmt.Errorf("MarketIndex should not be less than %d", MinMarketIndex)
|
||||
ErrMarketIndexTooHigh = fmt.Errorf("MarketIndex should not be larger than %d", MaxMarketIndex)
|
||||
ErrMarketIndexMismatch = fmt.Errorf("MarketIndex should match the market index of the order")
|
||||
ErrInitialMarginFractionTooLow = fmt.Errorf("InitialMarginFraction should not be less than %d", 0)
|
||||
ErrInitialMarginFractionTooHigh = fmt.Errorf("InitialMarginFraction should not be larger than %d", MarginFractionTick)
|
||||
ErrClientOrderIndexTooLow = fmt.Errorf("ClientOrderIndex should not be less than %d", MinClientOrderIndex)
|
||||
ErrClientOrderIndexTooHigh = fmt.Errorf("ClientOrderIndex should not be larger than %d", MaxClientOrderIndex)
|
||||
ErrClientOrderIndexNotNil = fmt.Errorf("ClientOrderIndex should be nil")
|
||||
ErrOrderIndexTooLow = fmt.Errorf("OrderIndex should not be less than %d", MinOrderIndex)
|
||||
ErrOrderIndexTooHigh = fmt.Errorf("OrderIndex should not be larger than %d", MaxOrderIndex)
|
||||
ErrBaseAmountTooLow = fmt.Errorf("BaseAmount should not be less than %d", MinOrderBaseAmount)
|
||||
ErrBaseAmountTooHigh = fmt.Errorf("BaseAmount should not be larger than %d", MaxOrderBaseAmount)
|
||||
ErrBaseAmountsNotEqual = fmt.Errorf("BaseAmounts should be equal")
|
||||
ErrBaseAmountNotNil = fmt.Errorf("BaseAmount should be nil")
|
||||
ErrPriceTooLow = fmt.Errorf("OrderPrice should not be less than %d", MinOrderPrice)
|
||||
ErrPriceTooHigh = fmt.Errorf("OrderPrice should not be larger than %d", MaxOrderPrice)
|
||||
ErrIsAskInvalid = fmt.Errorf("IsAsk should be 0 or 1")
|
||||
ErrOrderTypeInvalid = fmt.Errorf("OrderType is not valid")
|
||||
ErrOrderTimeInForceInvalid = fmt.Errorf("OrderTimeInForce is not valid")
|
||||
ErrGroupingTypeInvalid = fmt.Errorf("GroupingType is not valid")
|
||||
ErrOrderGroupSizeInvalid = fmt.Errorf("OrderGroupSize is not valid")
|
||||
ErrInvalidSignature = fmt.Errorf("TxSignature is invalid")
|
||||
ErrInvalidMarginMode = fmt.Errorf("MarginMode is not valid")
|
||||
ErrCancelModeInvalid = fmt.Errorf("CancelMode is not valid")
|
||||
ErrInvalidUpdateMarginDirection = fmt.Errorf("Margin movement direction is not valid")
|
||||
ErrTransferFeeNegative = fmt.Errorf("Transfer fee is negative")
|
||||
ErrTransferFeeTooHigh = fmt.Errorf("Transfer fee is higher than %d", MaxTransferAmount)
|
||||
)
|
||||
@@ -1,37 +0,0 @@
|
||||
package txtypes
|
||||
|
||||
import g "github.com/elliottech/poseidon_crypto/field/goldilocks"
|
||||
|
||||
type TxInfo interface {
|
||||
GetTxType() uint8
|
||||
|
||||
GetTxInfo() (string, error)
|
||||
|
||||
// GetTxHash returns the hash that was signed when creating this transaction.
|
||||
// The hash coincides with the TxHash received from Lighter after submitting this Tx.
|
||||
// It can be used to get the TxHash in advance, or to double-check the correctness of the SDK.
|
||||
// As this hash is signed by the ApiKey, if the value differs than the one computed by the server,
|
||||
// it'll result in an invalid signature.
|
||||
// Returns empty string if the Tx is not signed.
|
||||
GetTxHash() string
|
||||
|
||||
Validate() error
|
||||
|
||||
Hash(lighterChainId uint32, extra ...g.Element) (msgHash []byte, err error)
|
||||
}
|
||||
|
||||
type OrderInfo struct {
|
||||
MarketIndex uint8
|
||||
|
||||
ClientOrderIndex int64
|
||||
|
||||
BaseAmount int64
|
||||
Price uint32
|
||||
IsAsk uint8
|
||||
|
||||
Type uint8
|
||||
TimeInForce uint8
|
||||
ReduceOnly uint8
|
||||
TriggerPrice uint32
|
||||
OrderExpiry int64
|
||||
}
|
||||
@@ -1,91 +0,0 @@
|
||||
package txtypes
|
||||
|
||||
import (
|
||||
g "github.com/elliottech/poseidon_crypto/field/goldilocks"
|
||||
p2 "github.com/elliottech/poseidon_crypto/hash/poseidon2_goldilocks"
|
||||
)
|
||||
|
||||
var _ TxInfo = (*L2MintSharesTxInfo)(nil)
|
||||
|
||||
type L2MintSharesTxInfo struct {
|
||||
AccountIndex int64
|
||||
ApiKeyIndex uint8
|
||||
|
||||
PublicPoolIndex int64
|
||||
ShareAmount int64
|
||||
|
||||
ExpiredAt int64
|
||||
Nonce int64
|
||||
Sig []byte
|
||||
SignedHash string `json:"-"`
|
||||
}
|
||||
|
||||
func (txInfo *L2MintSharesTxInfo) GetTxType() uint8 {
|
||||
return TxTypeL2MintShares
|
||||
}
|
||||
|
||||
func (txInfo *L2MintSharesTxInfo) GetTxInfo() (string, error) {
|
||||
return getTxInfo(txInfo)
|
||||
}
|
||||
|
||||
func (txInfo *L2MintSharesTxInfo) GetTxHash() string {
|
||||
return txInfo.SignedHash
|
||||
}
|
||||
|
||||
func (txInfo *L2MintSharesTxInfo) Validate() error {
|
||||
if txInfo.AccountIndex < MinAccountIndex {
|
||||
return ErrFromAccountIndexTooLow
|
||||
}
|
||||
if txInfo.AccountIndex > MaxAccountIndex {
|
||||
return ErrFromAccountIndexTooHigh
|
||||
}
|
||||
|
||||
// ApiKeyIndex
|
||||
if txInfo.ApiKeyIndex < MinApiKeyIndex {
|
||||
return ErrApiKeyIndexTooLow
|
||||
}
|
||||
if txInfo.ApiKeyIndex > MaxApiKeyIndex {
|
||||
return ErrApiKeyIndexTooHigh
|
||||
}
|
||||
|
||||
// PublicPoolIndex
|
||||
if txInfo.PublicPoolIndex < MinAccountIndex {
|
||||
return ErrPublicPoolIndexTooLow
|
||||
}
|
||||
if txInfo.PublicPoolIndex > MaxAccountIndex {
|
||||
return ErrPublicPoolIndexTooHigh
|
||||
}
|
||||
|
||||
if txInfo.ShareAmount < MinPoolSharesToMintOrBurn {
|
||||
return ErrPoolMintShareAmountTooLow
|
||||
}
|
||||
if txInfo.ShareAmount > MaxPoolSharesToMintOrBurn {
|
||||
return ErrPoolMintShareAmountTooHigh
|
||||
}
|
||||
|
||||
if txInfo.Nonce < MinNonce {
|
||||
return ErrNonceTooLow
|
||||
}
|
||||
|
||||
if txInfo.ExpiredAt < 0 || txInfo.ExpiredAt > MaxTimestamp {
|
||||
return ErrExpiredAtInvalid
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (txInfo *L2MintSharesTxInfo) Hash(lighterChainId uint32, extra ...g.Element) (msgHash []byte, err error) {
|
||||
elems := make([]g.Element, 0, 8)
|
||||
|
||||
elems = append(elems, g.FromUint32(lighterChainId))
|
||||
elems = append(elems, g.FromUint32(TxTypeL2MintShares))
|
||||
elems = append(elems, g.FromInt64(txInfo.Nonce))
|
||||
elems = append(elems, g.FromInt64(txInfo.ExpiredAt))
|
||||
|
||||
elems = append(elems, g.FromInt64(txInfo.AccountIndex))
|
||||
elems = append(elems, g.FromUint32(uint32(txInfo.ApiKeyIndex)))
|
||||
elems = append(elems, g.FromInt64(txInfo.PublicPoolIndex))
|
||||
elems = append(elems, g.FromInt64(txInfo.ShareAmount))
|
||||
|
||||
return p2.HashToQuinticExtension(elems).ToLittleEndianBytes(), nil
|
||||
}
|
||||
@@ -1,120 +0,0 @@
|
||||
package txtypes
|
||||
|
||||
import (
|
||||
g "github.com/elliottech/poseidon_crypto/field/goldilocks"
|
||||
p2 "github.com/elliottech/poseidon_crypto/hash/poseidon2_goldilocks"
|
||||
)
|
||||
|
||||
var _ TxInfo = (*L2ModifyOrderTxInfo)(nil)
|
||||
|
||||
type L2ModifyOrderTxInfo struct {
|
||||
AccountIndex int64
|
||||
ApiKeyIndex uint8
|
||||
|
||||
MarketIndex uint8
|
||||
Index int64 // Client Order Index or Order Index of the order to modify
|
||||
BaseAmount int64
|
||||
Price uint32
|
||||
TriggerPrice uint32
|
||||
|
||||
ExpiredAt int64
|
||||
Nonce int64
|
||||
Sig []byte
|
||||
SignedHash string `json:"-"`
|
||||
}
|
||||
|
||||
func (txInfo *L2ModifyOrderTxInfo) GetTxType() uint8 {
|
||||
return TxTypeL2ModifyOrder
|
||||
}
|
||||
|
||||
func (txInfo *L2ModifyOrderTxInfo) GetTxInfo() (string, error) {
|
||||
return getTxInfo(txInfo)
|
||||
}
|
||||
|
||||
func (txInfo *L2ModifyOrderTxInfo) GetTxHash() string {
|
||||
return txInfo.SignedHash
|
||||
}
|
||||
|
||||
func (txInfo *L2ModifyOrderTxInfo) Validate() error {
|
||||
// AccountIndex
|
||||
if txInfo.AccountIndex < MinAccountIndex {
|
||||
return ErrAccountIndexTooLow
|
||||
}
|
||||
if txInfo.AccountIndex > MaxAccountIndex {
|
||||
return ErrAccountIndexTooHigh
|
||||
}
|
||||
// ApiKeyIndex
|
||||
if txInfo.ApiKeyIndex < MinApiKeyIndex {
|
||||
return ErrApiKeyIndexTooLow
|
||||
}
|
||||
if txInfo.ApiKeyIndex > MaxApiKeyIndex {
|
||||
return ErrApiKeyIndexTooHigh
|
||||
}
|
||||
|
||||
// MarketIndex
|
||||
if txInfo.MarketIndex < MinMarketIndex {
|
||||
return ErrMarketIndexTooLow
|
||||
}
|
||||
if txInfo.MarketIndex > MaxMarketIndex {
|
||||
return ErrMarketIndexTooHigh
|
||||
}
|
||||
|
||||
// Index
|
||||
if txInfo.Index < MinClientOrderIndex && txInfo.Index < MinOrderIndex {
|
||||
return ErrClientOrderIndexTooLow
|
||||
}
|
||||
if txInfo.Index > MaxClientOrderIndex && txInfo.Index > MaxOrderIndex {
|
||||
return ErrClientOrderIndexTooHigh
|
||||
}
|
||||
|
||||
// BaseAmount
|
||||
if txInfo.BaseAmount != NilOrderBaseAmount && txInfo.BaseAmount < MinOrderBaseAmount {
|
||||
return ErrBaseAmountTooLow
|
||||
}
|
||||
if txInfo.BaseAmount > MaxOrderBaseAmount {
|
||||
return ErrBaseAmountTooHigh
|
||||
}
|
||||
|
||||
// Price
|
||||
if txInfo.Price < MinOrderPrice {
|
||||
return ErrPriceTooLow
|
||||
}
|
||||
if txInfo.Price > MaxOrderPrice {
|
||||
return ErrPriceTooHigh
|
||||
}
|
||||
|
||||
// TriggerPrice
|
||||
if (txInfo.TriggerPrice < MinOrderTriggerPrice || txInfo.TriggerPrice > MaxOrderTriggerPrice) && txInfo.TriggerPrice != NilOrderTriggerPrice {
|
||||
return ErrOrderTriggerPriceInvalid
|
||||
}
|
||||
|
||||
// Nonce
|
||||
if txInfo.Nonce < MinNonce {
|
||||
return ErrNonceTooLow
|
||||
}
|
||||
|
||||
if txInfo.ExpiredAt < 0 || txInfo.ExpiredAt > MaxTimestamp {
|
||||
return ErrExpiredAtInvalid
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (txInfo *L2ModifyOrderTxInfo) Hash(lighterChainId uint32, extra ...g.Element) (msgHash []byte, err error) {
|
||||
elems := make([]g.Element, 0, 11)
|
||||
|
||||
elems = append(elems, g.FromUint32(lighterChainId))
|
||||
elems = append(elems, g.FromUint32(TxTypeL2ModifyOrder))
|
||||
elems = append(elems, g.FromInt64(txInfo.Nonce))
|
||||
elems = append(elems, g.FromInt64(txInfo.ExpiredAt))
|
||||
|
||||
elems = append(elems, g.FromInt64(txInfo.AccountIndex))
|
||||
elems = append(elems, g.FromUint32(uint32(txInfo.ApiKeyIndex)))
|
||||
elems = append(elems, g.FromUint32(uint32(txInfo.MarketIndex)))
|
||||
elems = append(elems, g.FromInt64(txInfo.Index))
|
||||
elems = append(elems, g.FromInt64(txInfo.BaseAmount))
|
||||
elems = append(elems, g.FromUint32(txInfo.Price))
|
||||
elems = append(elems, g.FromUint32(txInfo.TriggerPrice))
|
||||
|
||||
return p2.HashToQuinticExtension(elems).ToLittleEndianBytes(), nil
|
||||
}
|
||||
@@ -1,128 +0,0 @@
|
||||
package txtypes
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
g "github.com/elliottech/poseidon_crypto/field/goldilocks"
|
||||
p2 "github.com/elliottech/poseidon_crypto/hash/poseidon2_goldilocks"
|
||||
)
|
||||
|
||||
const templateTransfer = "Transfer\n\nnonce: %s\nfrom: %s\napi key: %s\nto: %s\namount: %s\nfee: %s\nmemo: %s\nOnly sign this message for a trusted client!"
|
||||
|
||||
var _ TxInfo = (*L2TransferTxInfo)(nil)
|
||||
|
||||
type L2TransferTxInfo struct {
|
||||
FromAccountIndex int64
|
||||
ApiKeyIndex uint8
|
||||
|
||||
ToAccountIndex int64
|
||||
USDCAmount int64 // USDCAmount is given with 6 decimals
|
||||
Fee int64
|
||||
Memo [32]byte
|
||||
|
||||
ExpiredAt int64
|
||||
Nonce int64
|
||||
Sig []byte
|
||||
SignedHash string `json:"-"`
|
||||
}
|
||||
|
||||
func (txInfo *L2TransferTxInfo) Validate() error {
|
||||
// plus one for treasury account
|
||||
if txInfo.FromAccountIndex < MinAccountIndex+1 {
|
||||
return ErrFromAccountIndexTooLow
|
||||
}
|
||||
if txInfo.FromAccountIndex > MaxAccountIndex {
|
||||
return ErrFromAccountIndexTooHigh
|
||||
}
|
||||
|
||||
// ApiKeyIndex
|
||||
if txInfo.ApiKeyIndex < MinApiKeyIndex {
|
||||
return ErrApiKeyIndexTooLow
|
||||
}
|
||||
|
||||
if txInfo.ApiKeyIndex > MaxApiKeyIndex {
|
||||
return ErrApiKeyIndexTooHigh
|
||||
}
|
||||
|
||||
if txInfo.ToAccountIndex < MinAccountIndex+1 {
|
||||
return ErrToAccountIndexTooLow
|
||||
}
|
||||
if txInfo.ToAccountIndex > MaxAccountIndex {
|
||||
return ErrToAccountIndexTooHigh
|
||||
}
|
||||
|
||||
if txInfo.USDCAmount <= 0 {
|
||||
return ErrTransferAmountTooLow
|
||||
}
|
||||
if txInfo.USDCAmount > MaxTransferAmount {
|
||||
return ErrTransferAmountTooHigh
|
||||
}
|
||||
|
||||
if txInfo.Fee < 0 {
|
||||
return ErrTransferFeeNegative
|
||||
}
|
||||
if txInfo.Fee > MaxTransferAmount {
|
||||
return ErrTransferFeeTooHigh
|
||||
}
|
||||
|
||||
if txInfo.Nonce < MinNonce {
|
||||
return ErrNonceTooLow
|
||||
}
|
||||
|
||||
if txInfo.ExpiredAt < 0 || txInfo.ExpiredAt > MaxTimestamp {
|
||||
return ErrExpiredAtInvalid
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (txInfo *L2TransferTxInfo) GetTxType() uint8 {
|
||||
return TxTypeL2Transfer
|
||||
}
|
||||
|
||||
func (txInfo *L2TransferTxInfo) GetTxHash() string {
|
||||
return txInfo.SignedHash
|
||||
}
|
||||
|
||||
func (txInfo *L2TransferTxInfo) GetTxInfo() (string, error) {
|
||||
return getTxInfo(txInfo)
|
||||
}
|
||||
|
||||
func (txInfo *L2TransferTxInfo) Hash(lighterChainId uint32, extra ...g.Element) (msgHash []byte, err error) {
|
||||
elems := make([]g.Element, 0, 11)
|
||||
|
||||
elems = append(elems, g.FromUint32(lighterChainId))
|
||||
elems = append(elems, g.FromUint32(TxTypeL2Transfer))
|
||||
elems = append(elems, g.FromInt64(txInfo.Nonce))
|
||||
elems = append(elems, g.FromInt64(txInfo.ExpiredAt))
|
||||
|
||||
elems = append(elems, g.FromInt64(txInfo.FromAccountIndex))
|
||||
elems = append(elems, g.FromUint32(uint32(txInfo.ApiKeyIndex)))
|
||||
elems = append(elems, g.FromInt64(txInfo.ToAccountIndex))
|
||||
elems = append(elems, g.FromUint64(uint64(txInfo.USDCAmount)&0xFFFFFFFF)) //nolint:gosec
|
||||
elems = append(elems, g.FromUint64(uint64(txInfo.USDCAmount)>>32)) //nolint:gosec
|
||||
elems = append(elems, g.FromUint64(uint64(txInfo.Fee)&0xFFFFFFFF)) //nolint:gosec
|
||||
elems = append(elems, g.FromUint64(uint64(txInfo.Fee)>>32)) //nolint:gosec
|
||||
|
||||
return p2.HashToQuinticExtension(elems).ToLittleEndianBytes(), nil
|
||||
}
|
||||
|
||||
func (txInfo *L2TransferTxInfo) GetL1SignatureBody() string {
|
||||
hexMemo := hex.EncodeToString(txInfo.Memo[:])
|
||||
hexMemo = strings.Replace(hexMemo, "0x", "", 1)
|
||||
|
||||
signatureBody := fmt.Sprintf(
|
||||
templateTransfer,
|
||||
|
||||
getHex10FromUint64(uint64(txInfo.Nonce)),
|
||||
getHex10FromUint64(uint64(txInfo.FromAccountIndex)),
|
||||
getHex10FromUint64(uint64(txInfo.ApiKeyIndex)),
|
||||
getHex10FromUint64(uint64(txInfo.ToAccountIndex)),
|
||||
getHex10FromUint64(uint64(txInfo.USDCAmount)),
|
||||
getHex10FromUint64(uint64(txInfo.Fee)),
|
||||
hexMemo,
|
||||
)
|
||||
return signatureBody
|
||||
}
|
||||
@@ -1,98 +0,0 @@
|
||||
package txtypes
|
||||
|
||||
import (
|
||||
g "github.com/elliottech/poseidon_crypto/field/goldilocks"
|
||||
p2 "github.com/elliottech/poseidon_crypto/hash/poseidon2_goldilocks"
|
||||
)
|
||||
|
||||
var _ TxInfo = (*L2UpdateLeverageTxInfo)(nil)
|
||||
|
||||
type L2UpdateLeverageTxInfo struct {
|
||||
AccountIndex int64
|
||||
ApiKeyIndex uint8
|
||||
|
||||
MarketIndex uint8
|
||||
InitialMarginFraction uint16
|
||||
MarginMode uint8
|
||||
|
||||
ExpiredAt int64
|
||||
Nonce int64
|
||||
Sig []byte
|
||||
SignedHash string `json:"-"`
|
||||
}
|
||||
|
||||
func (txInfo *L2UpdateLeverageTxInfo) GetTxType() uint8 {
|
||||
return TxTypeL2UpdateLeverage
|
||||
}
|
||||
|
||||
func (txInfo *L2UpdateLeverageTxInfo) GetTxInfo() (string, error) {
|
||||
return getTxInfo(txInfo)
|
||||
}
|
||||
|
||||
func (txInfo *L2UpdateLeverageTxInfo) GetTxHash() string {
|
||||
return txInfo.SignedHash
|
||||
}
|
||||
|
||||
func (txInfo *L2UpdateLeverageTxInfo) Validate() error {
|
||||
if txInfo.AccountIndex < MinAccountIndex {
|
||||
return ErrFromAccountIndexTooLow
|
||||
}
|
||||
if txInfo.AccountIndex > MaxAccountIndex {
|
||||
return ErrFromAccountIndexTooHigh
|
||||
}
|
||||
|
||||
// ApiKeyIndex
|
||||
if txInfo.ApiKeyIndex < MinApiKeyIndex {
|
||||
return ErrApiKeyIndexTooLow
|
||||
}
|
||||
if txInfo.ApiKeyIndex > MaxApiKeyIndex {
|
||||
return ErrApiKeyIndexTooHigh
|
||||
}
|
||||
|
||||
// MarketIndex
|
||||
if txInfo.MarketIndex < MinMarketIndex {
|
||||
return ErrMarketIndexTooLow
|
||||
}
|
||||
if txInfo.MarketIndex > MaxMarketIndex {
|
||||
return ErrMarketIndexTooHigh
|
||||
}
|
||||
|
||||
// InitialMarginFraction
|
||||
if txInfo.InitialMarginFraction <= 0 {
|
||||
return ErrInitialMarginFractionTooLow
|
||||
}
|
||||
if txInfo.InitialMarginFraction > uint16(MarginFractionTick) { //nolint:gosec
|
||||
return ErrInitialMarginFractionTooHigh
|
||||
}
|
||||
|
||||
if txInfo.Nonce < MinNonce {
|
||||
return ErrNonceTooLow
|
||||
}
|
||||
|
||||
if txInfo.ExpiredAt < 0 || txInfo.ExpiredAt > MaxTimestamp {
|
||||
return ErrExpiredAtInvalid
|
||||
}
|
||||
|
||||
if txInfo.MarginMode != CrossMargin && txInfo.MarginMode != IsolatedMargin {
|
||||
return ErrInvalidMarginMode
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (txInfo *L2UpdateLeverageTxInfo) Hash(lighterChainId uint32, extra ...g.Element) (msgHash []byte, err error) {
|
||||
elems := make([]g.Element, 0, 9)
|
||||
|
||||
elems = append(elems, g.FromUint32(lighterChainId))
|
||||
elems = append(elems, g.FromUint32(TxTypeL2UpdateLeverage))
|
||||
elems = append(elems, g.FromInt64(txInfo.Nonce))
|
||||
elems = append(elems, g.FromInt64(txInfo.ExpiredAt))
|
||||
|
||||
elems = append(elems, g.FromInt64(txInfo.AccountIndex))
|
||||
elems = append(elems, g.FromUint32(uint32(txInfo.ApiKeyIndex)))
|
||||
elems = append(elems, g.FromInt64(int64(txInfo.MarketIndex)))
|
||||
elems = append(elems, g.FromInt64(int64(txInfo.InitialMarginFraction)))
|
||||
elems = append(elems, g.FromUint32(uint32(txInfo.MarginMode)))
|
||||
|
||||
return p2.HashToQuinticExtension(elems).ToLittleEndianBytes(), nil
|
||||
}
|
||||
@@ -1,98 +0,0 @@
|
||||
package txtypes
|
||||
|
||||
import (
|
||||
g "github.com/elliottech/poseidon_crypto/field/goldilocks"
|
||||
p2 "github.com/elliottech/poseidon_crypto/hash/poseidon2_goldilocks"
|
||||
)
|
||||
|
||||
var _ TxInfo = (*L2UpdateMarginTxInfo)(nil)
|
||||
|
||||
type L2UpdateMarginTxInfo struct {
|
||||
AccountIndex int64
|
||||
ApiKeyIndex uint8
|
||||
|
||||
MarketIndex uint8
|
||||
USDCAmount int64
|
||||
Direction uint8
|
||||
|
||||
ExpiredAt int64
|
||||
Nonce int64
|
||||
Sig []byte
|
||||
SignedHash string `json:"-"`
|
||||
}
|
||||
|
||||
func (txInfo *L2UpdateMarginTxInfo) GetTxType() uint8 {
|
||||
return TxTypeL2UpdateMargin
|
||||
}
|
||||
|
||||
func (txInfo *L2UpdateMarginTxInfo) GetTxInfo() (string, error) {
|
||||
return getTxInfo(txInfo)
|
||||
}
|
||||
|
||||
func (txInfo *L2UpdateMarginTxInfo) GetTxHash() string {
|
||||
return txInfo.SignedHash
|
||||
}
|
||||
|
||||
func (txInfo *L2UpdateMarginTxInfo) Validate() error {
|
||||
if txInfo.AccountIndex < MinAccountIndex {
|
||||
return ErrFromAccountIndexTooLow
|
||||
}
|
||||
if txInfo.AccountIndex > MaxAccountIndex {
|
||||
return ErrFromAccountIndexTooHigh
|
||||
}
|
||||
|
||||
// ApiKeyIndex
|
||||
if txInfo.ApiKeyIndex < MinApiKeyIndex {
|
||||
return ErrApiKeyIndexTooLow
|
||||
}
|
||||
if txInfo.ApiKeyIndex > MaxApiKeyIndex {
|
||||
return ErrApiKeyIndexTooHigh
|
||||
}
|
||||
|
||||
// MarketIndex
|
||||
if txInfo.MarketIndex < MinMarketIndex {
|
||||
return ErrMarketIndexTooLow
|
||||
}
|
||||
if txInfo.MarketIndex > MaxMarketIndex {
|
||||
return ErrMarketIndexTooHigh
|
||||
}
|
||||
|
||||
if txInfo.USDCAmount <= 0 {
|
||||
return ErrTransferAmountTooLow
|
||||
}
|
||||
if txInfo.USDCAmount > MaxTransferAmount {
|
||||
return ErrTransferAmountTooHigh
|
||||
}
|
||||
|
||||
if txInfo.Direction != RemoveFromIsolatedMargin && txInfo.Direction != AddToIsolatedMargin {
|
||||
return ErrInvalidUpdateMarginDirection
|
||||
}
|
||||
|
||||
if txInfo.Nonce < MinNonce {
|
||||
return ErrNonceTooLow
|
||||
}
|
||||
|
||||
if txInfo.ExpiredAt < 0 || txInfo.ExpiredAt > MaxTimestamp {
|
||||
return ErrExpiredAtInvalid
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (txInfo *L2UpdateMarginTxInfo) Hash(lighterChainId uint32, extra ...g.Element) (msgHash []byte, err error) {
|
||||
elems := make([]g.Element, 0, 10)
|
||||
|
||||
elems = append(elems, g.FromUint32(lighterChainId))
|
||||
elems = append(elems, g.FromUint32(TxTypeL2UpdateMargin))
|
||||
elems = append(elems, g.FromInt64(txInfo.Nonce))
|
||||
elems = append(elems, g.FromInt64(txInfo.ExpiredAt))
|
||||
|
||||
elems = append(elems, g.FromInt64(txInfo.AccountIndex))
|
||||
elems = append(elems, g.FromUint32(uint32(txInfo.ApiKeyIndex)))
|
||||
elems = append(elems, g.FromInt64(int64(txInfo.MarketIndex)))
|
||||
elems = append(elems, g.FromUint64(uint64(txInfo.USDCAmount)&0xFFFFFFFF)) //nolint:gosec
|
||||
elems = append(elems, g.FromUint64(uint64(txInfo.USDCAmount)>>32)) //nolint:gosec
|
||||
elems = append(elems, g.FromUint32(uint32(txInfo.Direction)))
|
||||
|
||||
return p2.HashToQuinticExtension(elems).ToLittleEndianBytes(), nil
|
||||
}
|
||||
@@ -1,109 +0,0 @@
|
||||
package txtypes
|
||||
|
||||
import (
|
||||
g "github.com/elliottech/poseidon_crypto/field/goldilocks"
|
||||
p2 "github.com/elliottech/poseidon_crypto/hash/poseidon2_goldilocks"
|
||||
)
|
||||
|
||||
var _ TxInfo = (*L2UpdatePublicPoolTxInfo)(nil)
|
||||
|
||||
type L2UpdatePublicPoolTxInfo struct {
|
||||
AccountIndex int64 // Master account index
|
||||
ApiKeyIndex uint8
|
||||
|
||||
PublicPoolIndex int64
|
||||
|
||||
Status uint8
|
||||
OperatorFee int64
|
||||
MinOperatorShareRate int64
|
||||
|
||||
ExpiredAt int64
|
||||
Nonce int64
|
||||
Sig []byte
|
||||
SignedHash string `json:"-"`
|
||||
}
|
||||
|
||||
func (txInfo *L2UpdatePublicPoolTxInfo) GetTxType() uint8 {
|
||||
return TxTypeL2UpdatePublicPool
|
||||
}
|
||||
|
||||
func (txInfo *L2UpdatePublicPoolTxInfo) GetTxInfo() (string, error) {
|
||||
return getTxInfo(txInfo)
|
||||
}
|
||||
|
||||
func (txInfo *L2UpdatePublicPoolTxInfo) GetTxHash() string {
|
||||
return txInfo.SignedHash
|
||||
}
|
||||
|
||||
func (txInfo *L2UpdatePublicPoolTxInfo) Validate() error {
|
||||
// AccountIndex
|
||||
if txInfo.AccountIndex < MinAccountIndex {
|
||||
return ErrFromAccountIndexTooLow
|
||||
}
|
||||
if txInfo.AccountIndex > MaxAccountIndex {
|
||||
return ErrFromAccountIndexTooHigh
|
||||
}
|
||||
|
||||
// ApiKeyIndex
|
||||
if txInfo.ApiKeyIndex < MinApiKeyIndex {
|
||||
return ErrApiKeyIndexTooLow
|
||||
}
|
||||
if txInfo.ApiKeyIndex > MaxApiKeyIndex {
|
||||
return ErrApiKeyIndexTooHigh
|
||||
}
|
||||
|
||||
// PublicPoolIndex
|
||||
if txInfo.PublicPoolIndex < MinAccountIndex {
|
||||
return ErrPublicPoolIndexTooLow
|
||||
}
|
||||
if txInfo.PublicPoolIndex > MaxAccountIndex {
|
||||
return ErrPublicPoolIndexTooHigh
|
||||
}
|
||||
|
||||
// Status
|
||||
if txInfo.Status != 0 && txInfo.Status != 1 {
|
||||
return ErrInvalidPoolStatus
|
||||
}
|
||||
|
||||
// OperatorFee
|
||||
if txInfo.OperatorFee < 0 || txInfo.OperatorFee > FeeTick {
|
||||
return ErrInvalidPoolOperatorFee
|
||||
}
|
||||
|
||||
// MinOperatorShareRate
|
||||
if txInfo.MinOperatorShareRate < 0 {
|
||||
return ErrPoolMinOperatorShareRateTooLow
|
||||
}
|
||||
if txInfo.MinOperatorShareRate > ShareTick {
|
||||
return ErrPoolMinOperatorShareRateTooHigh
|
||||
}
|
||||
|
||||
// Nonce
|
||||
if txInfo.Nonce < MinNonce {
|
||||
return ErrNonceTooLow
|
||||
}
|
||||
|
||||
if txInfo.ExpiredAt < 0 || txInfo.ExpiredAt > MaxTimestamp {
|
||||
return ErrExpiredAtInvalid
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (txInfo *L2UpdatePublicPoolTxInfo) Hash(lighterChainId uint32, extra ...g.Element) (msgHash []byte, err error) {
|
||||
elems := make([]g.Element, 0, 10)
|
||||
|
||||
elems = append(elems, g.FromUint32(lighterChainId))
|
||||
elems = append(elems, g.FromUint32(TxTypeL2UpdatePublicPool))
|
||||
elems = append(elems, g.FromInt64(txInfo.Nonce))
|
||||
elems = append(elems, g.FromInt64(txInfo.ExpiredAt))
|
||||
|
||||
elems = append(elems, g.FromInt64(txInfo.AccountIndex))
|
||||
elems = append(elems, g.FromUint32(uint32(txInfo.ApiKeyIndex)))
|
||||
elems = append(elems, g.FromInt64(txInfo.PublicPoolIndex))
|
||||
elems = append(elems, g.FromUint32(uint32(txInfo.Status)))
|
||||
elems = append(elems, g.FromInt64(txInfo.OperatorFee))
|
||||
elems = append(elems, g.FromInt64(txInfo.MinOperatorShareRate))
|
||||
|
||||
return p2.HashToQuinticExtension(elems).ToLittleEndianBytes(), nil
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
package txtypes
|
||||
|
||||
import "encoding/json"
|
||||
|
||||
func IsValidPubKey(bytes []byte) bool {
|
||||
if len(bytes) != 40 {
|
||||
return false
|
||||
}
|
||||
|
||||
return !isZeroByteSlice(bytes)
|
||||
}
|
||||
|
||||
func isZeroByteSlice(bytes []byte) bool {
|
||||
for _, s := range bytes {
|
||||
if s != 0 {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func getTxInfo(tx interface{}) (string, error) {
|
||||
txInfoBytes, err := json.Marshal(tx)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(txInfoBytes), nil
|
||||
}
|
||||
@@ -1,82 +0,0 @@
|
||||
package txtypes
|
||||
|
||||
import (
|
||||
g "github.com/elliottech/poseidon_crypto/field/goldilocks"
|
||||
p2 "github.com/elliottech/poseidon_crypto/hash/poseidon2_goldilocks"
|
||||
)
|
||||
|
||||
var _ TxInfo = (*L2WithdrawTxInfo)(nil)
|
||||
|
||||
type L2WithdrawTxInfo struct {
|
||||
FromAccountIndex int64
|
||||
ApiKeyIndex uint8
|
||||
|
||||
USDCAmount uint64 // USDCAmount is given with 6 decimals
|
||||
|
||||
ExpiredAt int64
|
||||
Nonce int64
|
||||
Sig []byte
|
||||
SignedHash string `json:"-"`
|
||||
}
|
||||
|
||||
func (txInfo *L2WithdrawTxInfo) Validate() error {
|
||||
if txInfo.FromAccountIndex < MinAccountIndex {
|
||||
return ErrFromAccountIndexTooLow
|
||||
}
|
||||
if txInfo.FromAccountIndex > MaxAccountIndex {
|
||||
return ErrFromAccountIndexTooHigh
|
||||
}
|
||||
|
||||
// ApiKeyIndex
|
||||
if txInfo.ApiKeyIndex < MinApiKeyIndex {
|
||||
return ErrApiKeyIndexTooLow
|
||||
}
|
||||
if txInfo.ApiKeyIndex > MaxApiKeyIndex {
|
||||
return ErrApiKeyIndexTooHigh
|
||||
}
|
||||
|
||||
if txInfo.USDCAmount == 0 {
|
||||
return ErrWithdrawalAmountTooLow
|
||||
}
|
||||
if txInfo.USDCAmount > MaxWithdrawalAmount {
|
||||
return ErrWithdrawalAmountTooHigh
|
||||
}
|
||||
|
||||
if txInfo.Nonce < MinNonce {
|
||||
return ErrNonceTooLow
|
||||
}
|
||||
|
||||
if txInfo.ExpiredAt < 0 || txInfo.ExpiredAt > MaxTimestamp {
|
||||
return ErrExpiredAtInvalid
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (txInfo *L2WithdrawTxInfo) GetTxType() uint8 {
|
||||
return TxTypeL2Withdraw
|
||||
}
|
||||
|
||||
func (txInfo *L2WithdrawTxInfo) GetTxInfo() (string, error) {
|
||||
return getTxInfo(txInfo)
|
||||
}
|
||||
|
||||
func (txInfo *L2WithdrawTxInfo) GetTxHash() string {
|
||||
return txInfo.SignedHash
|
||||
}
|
||||
|
||||
func (txInfo *L2WithdrawTxInfo) Hash(lighterChainId uint32, extra ...g.Element) (msgHash []byte, err error) {
|
||||
elems := make([]g.Element, 0, 8)
|
||||
|
||||
elems = append(elems, g.FromUint32(lighterChainId))
|
||||
elems = append(elems, g.FromUint32(TxTypeL2Withdraw))
|
||||
elems = append(elems, g.FromInt64(txInfo.Nonce))
|
||||
elems = append(elems, g.FromInt64(txInfo.ExpiredAt))
|
||||
|
||||
elems = append(elems, g.FromInt64(txInfo.FromAccountIndex))
|
||||
elems = append(elems, g.FromUint32(uint32(txInfo.ApiKeyIndex)))
|
||||
elems = append(elems, g.FromUint64(uint64(txInfo.USDCAmount)&0xFFFFFFFF)) //nolint:gosec
|
||||
elems = append(elems, g.FromUint64(uint64(txInfo.USDCAmount)>>32)) //nolint:gosec
|
||||
|
||||
return p2.HashToQuinticExtension(elems).ToLittleEndianBytes(), nil
|
||||
}
|
||||
@@ -68,4 +68,9 @@ openapi-generator-cli.jar
|
||||
|
||||
.idea
|
||||
|
||||
examples/secrets.py
|
||||
examples/secrets.py
|
||||
|
||||
# Environment variables
|
||||
.env
|
||||
.env.*
|
||||
api_key_config.json
|
||||
@@ -1,6 +1,7 @@
|
||||
docs/Account.md
|
||||
docs/AccountApi.md
|
||||
docs/AccountApiKeys.md
|
||||
docs/AccountAsset.md
|
||||
docs/AccountLimits.md
|
||||
docs/AccountMarginStats.md
|
||||
docs/AccountMarketStats.md
|
||||
@@ -14,9 +15,12 @@ docs/Announcement.md
|
||||
docs/AnnouncementApi.md
|
||||
docs/Announcements.md
|
||||
docs/ApiKey.md
|
||||
docs/Asset.md
|
||||
docs/AssetDetails.md
|
||||
docs/Block.md
|
||||
docs/BlockApi.md
|
||||
docs/Blocks.md
|
||||
docs/Bridge.md
|
||||
docs/BridgeApi.md
|
||||
docs/BridgeSupportedNetwork.md
|
||||
docs/Candlestick.md
|
||||
@@ -46,28 +50,27 @@ docs/LiqTrade.md
|
||||
docs/Liquidation.md
|
||||
docs/LiquidationInfo.md
|
||||
docs/LiquidationInfos.md
|
||||
docs/MarketInfo.md
|
||||
docs/MarketConfig.md
|
||||
docs/NextNonce.md
|
||||
docs/NotificationApi.md
|
||||
docs/Order.md
|
||||
docs/OrderApi.md
|
||||
docs/OrderBook.md
|
||||
docs/OrderBookDepth.md
|
||||
docs/OrderBookDetail.md
|
||||
docs/OrderBookDetails.md
|
||||
docs/OrderBookOrders.md
|
||||
docs/OrderBookStats.md
|
||||
docs/OrderBooks.md
|
||||
docs/Orders.md
|
||||
docs/PerpsMarketStats.md
|
||||
docs/PerpsOrderBookDetail.md
|
||||
docs/PnLEntry.md
|
||||
docs/PositionFunding.md
|
||||
docs/PositionFundings.md
|
||||
docs/PriceLevel.md
|
||||
docs/PublicPool.md
|
||||
docs/PublicPoolInfo.md
|
||||
docs/PublicPoolMetadata.md
|
||||
docs/PublicPoolShare.md
|
||||
docs/PublicPools.md
|
||||
docs/ReferralApi.md
|
||||
docs/ReferralPointEntry.md
|
||||
docs/ReferralPoints.md
|
||||
@@ -81,8 +84,10 @@ docs/ReqGetAccountLimits.md
|
||||
docs/ReqGetAccountMetadata.md
|
||||
docs/ReqGetAccountPnL.md
|
||||
docs/ReqGetAccountTxs.md
|
||||
docs/ReqGetAssetDetails.md
|
||||
docs/ReqGetBlock.md
|
||||
docs/ReqGetBlockTxs.md
|
||||
docs/ReqGetBridgesByL1Addr.md
|
||||
docs/ReqGetByAccount.md
|
||||
docs/ReqGetCandlesticks.md
|
||||
docs/ReqGetDepositHistory.md
|
||||
@@ -97,7 +102,6 @@ docs/ReqGetOrderBookDetails.md
|
||||
docs/ReqGetOrderBookOrders.md
|
||||
docs/ReqGetOrderBooks.md
|
||||
docs/ReqGetPositionFunding.md
|
||||
docs/ReqGetPublicPools.md
|
||||
docs/ReqGetPublicPoolsMetadata.md
|
||||
docs/ReqGetRangeWithCursor.md
|
||||
docs/ReqGetRangeWithIndex.md
|
||||
@@ -110,10 +114,14 @@ docs/ReqGetTransferHistory.md
|
||||
docs/ReqGetTx.md
|
||||
docs/ReqGetWithdrawHistory.md
|
||||
docs/RespChangeAccountTier.md
|
||||
docs/RespGetBridgesByL1Addr.md
|
||||
docs/RespGetFastBridgeInfo.md
|
||||
docs/RespGetIsNextBridgeFast.md
|
||||
docs/RespPublicPoolsMetadata.md
|
||||
docs/RespSendTx.md
|
||||
docs/RespSendTxBatch.md
|
||||
docs/RespUpdateKickback.md
|
||||
docs/RespUpdateReferralCode.md
|
||||
docs/RespWithdrawalDelay.md
|
||||
docs/ResultCode.md
|
||||
docs/RiskInfo.md
|
||||
@@ -121,6 +129,8 @@ docs/RiskParameters.md
|
||||
docs/RootApi.md
|
||||
docs/SharePrice.md
|
||||
docs/SimpleOrder.md
|
||||
docs/SpotMarketStats.md
|
||||
docs/SpotOrderBookDetail.md
|
||||
docs/Status.md
|
||||
docs/SubAccounts.md
|
||||
docs/Ticker.md
|
||||
@@ -160,6 +170,7 @@ lighter/exceptions.py
|
||||
lighter/models/__init__.py
|
||||
lighter/models/account.py
|
||||
lighter/models/account_api_keys.py
|
||||
lighter/models/account_asset.py
|
||||
lighter/models/account_limits.py
|
||||
lighter/models/account_margin_stats.py
|
||||
lighter/models/account_market_stats.py
|
||||
@@ -172,8 +183,11 @@ lighter/models/account_trade_stats.py
|
||||
lighter/models/announcement.py
|
||||
lighter/models/announcements.py
|
||||
lighter/models/api_key.py
|
||||
lighter/models/asset.py
|
||||
lighter/models/asset_details.py
|
||||
lighter/models/block.py
|
||||
lighter/models/blocks.py
|
||||
lighter/models/bridge.py
|
||||
lighter/models/bridge_supported_network.py
|
||||
lighter/models/candlestick.py
|
||||
lighter/models/candlesticks.py
|
||||
@@ -199,26 +213,25 @@ lighter/models/liq_trade.py
|
||||
lighter/models/liquidation.py
|
||||
lighter/models/liquidation_info.py
|
||||
lighter/models/liquidation_infos.py
|
||||
lighter/models/market_info.py
|
||||
lighter/models/market_config.py
|
||||
lighter/models/next_nonce.py
|
||||
lighter/models/order.py
|
||||
lighter/models/order_book.py
|
||||
lighter/models/order_book_depth.py
|
||||
lighter/models/order_book_detail.py
|
||||
lighter/models/order_book_details.py
|
||||
lighter/models/order_book_orders.py
|
||||
lighter/models/order_book_stats.py
|
||||
lighter/models/order_books.py
|
||||
lighter/models/orders.py
|
||||
lighter/models/perps_market_stats.py
|
||||
lighter/models/perps_order_book_detail.py
|
||||
lighter/models/pn_l_entry.py
|
||||
lighter/models/position_funding.py
|
||||
lighter/models/position_fundings.py
|
||||
lighter/models/price_level.py
|
||||
lighter/models/public_pool.py
|
||||
lighter/models/public_pool_info.py
|
||||
lighter/models/public_pool_metadata.py
|
||||
lighter/models/public_pool_share.py
|
||||
lighter/models/public_pools.py
|
||||
lighter/models/referral_point_entry.py
|
||||
lighter/models/referral_points.py
|
||||
lighter/models/req_export_data.py
|
||||
@@ -231,8 +244,10 @@ lighter/models/req_get_account_limits.py
|
||||
lighter/models/req_get_account_metadata.py
|
||||
lighter/models/req_get_account_pn_l.py
|
||||
lighter/models/req_get_account_txs.py
|
||||
lighter/models/req_get_asset_details.py
|
||||
lighter/models/req_get_block.py
|
||||
lighter/models/req_get_block_txs.py
|
||||
lighter/models/req_get_bridges_by_l1_addr.py
|
||||
lighter/models/req_get_by_account.py
|
||||
lighter/models/req_get_candlesticks.py
|
||||
lighter/models/req_get_deposit_history.py
|
||||
@@ -247,7 +262,6 @@ lighter/models/req_get_order_book_details.py
|
||||
lighter/models/req_get_order_book_orders.py
|
||||
lighter/models/req_get_order_books.py
|
||||
lighter/models/req_get_position_funding.py
|
||||
lighter/models/req_get_public_pools.py
|
||||
lighter/models/req_get_public_pools_metadata.py
|
||||
lighter/models/req_get_range_with_cursor.py
|
||||
lighter/models/req_get_range_with_index.py
|
||||
@@ -260,16 +274,22 @@ lighter/models/req_get_transfer_history.py
|
||||
lighter/models/req_get_tx.py
|
||||
lighter/models/req_get_withdraw_history.py
|
||||
lighter/models/resp_change_account_tier.py
|
||||
lighter/models/resp_get_bridges_by_l1_addr.py
|
||||
lighter/models/resp_get_fast_bridge_info.py
|
||||
lighter/models/resp_get_is_next_bridge_fast.py
|
||||
lighter/models/resp_public_pools_metadata.py
|
||||
lighter/models/resp_send_tx.py
|
||||
lighter/models/resp_send_tx_batch.py
|
||||
lighter/models/resp_update_kickback.py
|
||||
lighter/models/resp_update_referral_code.py
|
||||
lighter/models/resp_withdrawal_delay.py
|
||||
lighter/models/result_code.py
|
||||
lighter/models/risk_info.py
|
||||
lighter/models/risk_parameters.py
|
||||
lighter/models/share_price.py
|
||||
lighter/models/simple_order.py
|
||||
lighter/models/spot_market_stats.py
|
||||
lighter/models/spot_order_book_detail.py
|
||||
lighter/models/status.py
|
||||
lighter/models/sub_accounts.py
|
||||
lighter/models/ticker.py
|
||||
@@ -291,4 +311,19 @@ lighter/rest.py
|
||||
setup.cfg
|
||||
test-requirements.txt
|
||||
test/__init__.py
|
||||
test/test_account_asset.py
|
||||
test/test_asset.py
|
||||
test/test_asset_details.py
|
||||
test/test_bridge.py
|
||||
test/test_market_config.py
|
||||
test/test_perps_market_stats.py
|
||||
test/test_perps_order_book_detail.py
|
||||
test/test_req_get_asset_details.py
|
||||
test/test_req_get_bridges_by_l1_addr.py
|
||||
test/test_resp_get_bridges_by_l1_addr.py
|
||||
test/test_resp_get_is_next_bridge_fast.py
|
||||
test/test_resp_update_kickback.py
|
||||
test/test_resp_update_referral_code.py
|
||||
test/test_spot_market_stats.py
|
||||
test/test_spot_order_book_detail.py
|
||||
tox.ini
|
||||
|
||||
@@ -0,0 +1,201 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
@@ -36,9 +36,12 @@ import asyncio
|
||||
|
||||
async def main():
|
||||
client = lighter.ApiClient()
|
||||
account_api = lighter.AccountApi(client)
|
||||
account = await account_api.get_account(by="index", value="1")
|
||||
print(account)
|
||||
try:
|
||||
account_api = lighter.AccountApi(client)
|
||||
account = await account_api.account(by="index", value="1")
|
||||
print(account)
|
||||
finally:
|
||||
await client.close() # Make sure connection is cleanly closed
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
disallowAdditionalPropertiesIfNotPresent: false
|
||||
library: asyncio
|
||||
packageName: lighter-sdk
|
||||
projectName: lighter-sdk
|
||||
@@ -12,7 +12,6 @@ Name | Type | Description | Notes
|
||||
**l1_address** | **str** | |
|
||||
**cancel_all_time** | **int** | |
|
||||
**total_order_count** | **int** | |
|
||||
**total_isolated_order_count** | **int** | |
|
||||
**pending_order_count** | **int** | |
|
||||
**available_balance** | **str** | |
|
||||
**status** | **int** | |
|
||||
|
||||
@@ -14,7 +14,6 @@ Method | HTTP request | Description
|
||||
[**liquidations**](AccountApi.md#liquidations) | **GET** /api/v1/liquidations | liquidations
|
||||
[**pnl**](AccountApi.md#pnl) | **GET** /api/v1/pnl | pnl
|
||||
[**position_funding**](AccountApi.md#position_funding) | **GET** /api/v1/positionFunding | positionFunding
|
||||
[**public_pools**](AccountApi.md#public_pools) | **GET** /api/v1/publicPools | publicPools
|
||||
[**public_pools_metadata**](AccountApi.md#public_pools_metadata) | **GET** /api/v1/publicPoolsMetadata | publicPoolsMetadata
|
||||
|
||||
|
||||
@@ -770,85 +769,6 @@ No authorization required
|
||||
|
||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
||||
|
||||
# **public_pools**
|
||||
> PublicPools public_pools(index, limit, authorization=authorization, auth=auth, filter=filter, account_index=account_index)
|
||||
|
||||
publicPools
|
||||
|
||||
Get public pools
|
||||
|
||||
### Example
|
||||
|
||||
|
||||
```python
|
||||
import lighter
|
||||
from lighter.models.public_pools import PublicPools
|
||||
from lighter.rest import ApiException
|
||||
from pprint import pprint
|
||||
|
||||
# Defining the host is optional and defaults to https://mainnet.zklighter.elliot.ai
|
||||
# See configuration.py for a list of all supported configuration parameters.
|
||||
configuration = lighter.Configuration(
|
||||
host = "https://mainnet.zklighter.elliot.ai"
|
||||
)
|
||||
|
||||
|
||||
# Enter a context with an instance of the API client
|
||||
async with lighter.ApiClient(configuration) as api_client:
|
||||
# Create an instance of the API class
|
||||
api_instance = lighter.AccountApi(api_client)
|
||||
index = 56 # int |
|
||||
limit = 56 # int |
|
||||
authorization = 'authorization_example' # str | (optional)
|
||||
auth = 'auth_example' # str | (optional)
|
||||
filter = 'filter_example' # str | (optional)
|
||||
account_index = 56 # int | (optional)
|
||||
|
||||
try:
|
||||
# publicPools
|
||||
api_response = await api_instance.public_pools(index, limit, authorization=authorization, auth=auth, filter=filter, account_index=account_index)
|
||||
print("The response of AccountApi->public_pools:\n")
|
||||
pprint(api_response)
|
||||
except Exception as e:
|
||||
print("Exception when calling AccountApi->public_pools: %s\n" % e)
|
||||
```
|
||||
|
||||
|
||||
|
||||
### Parameters
|
||||
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------- | ------------- | ------------- | -------------
|
||||
**index** | **int**| |
|
||||
**limit** | **int**| |
|
||||
**authorization** | **str**| | [optional]
|
||||
**auth** | **str**| | [optional]
|
||||
**filter** | **str**| | [optional]
|
||||
**account_index** | **int**| | [optional]
|
||||
|
||||
### Return type
|
||||
|
||||
[**PublicPools**](PublicPools.md)
|
||||
|
||||
### Authorization
|
||||
|
||||
No authorization required
|
||||
|
||||
### HTTP request headers
|
||||
|
||||
- **Content-Type**: Not defined
|
||||
- **Accept**: application/json
|
||||
|
||||
### HTTP response details
|
||||
|
||||
| Status code | Description | Response headers |
|
||||
|-------------|-------------|------------------|
|
||||
**200** | A successful response. | - |
|
||||
**400** | Bad request | - |
|
||||
|
||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
||||
|
||||
# **public_pools_metadata**
|
||||
> RespPublicPoolsMetadata public_pools_metadata(index, limit, authorization=authorization, auth=auth, filter=filter, account_index=account_index)
|
||||
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
# AccountAsset
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**symbol** | **str** | |
|
||||
**asset_id** | **int** | |
|
||||
**balance** | **str** | |
|
||||
**locked_balance** | **str** | |
|
||||
|
||||
## Example
|
||||
|
||||
```python
|
||||
from lighter.models.account_asset import AccountAsset
|
||||
|
||||
# TODO update the JSON string below
|
||||
json = "{}"
|
||||
# create an instance of AccountAsset from a JSON string
|
||||
account_asset_instance = AccountAsset.from_json(json)
|
||||
# print the JSON string representation of the object
|
||||
print(AccountAsset.to_json())
|
||||
|
||||
# convert the object into a dict
|
||||
account_asset_dict = account_asset_instance.to_dict()
|
||||
# create an instance of AccountAsset from a dict
|
||||
account_asset_from_dict = AccountAsset.from_dict(account_asset_dict)
|
||||
```
|
||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||
|
||||
|
||||
@@ -8,7 +8,9 @@ Name | Type | Description | Notes
|
||||
**code** | **int** | |
|
||||
**message** | **str** | | [optional]
|
||||
**max_llp_percentage** | **int** | |
|
||||
**max_llp_amount** | **str** | |
|
||||
**user_tier** | **str** | |
|
||||
**can_create_public_pool** | **bool** | |
|
||||
|
||||
## Example
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ Name | Type | Description | Notes
|
||||
**title** | **str** | |
|
||||
**content** | **str** | |
|
||||
**created_at** | **int** | |
|
||||
**expired_at** | **int** | |
|
||||
|
||||
## Example
|
||||
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
# Asset
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**asset_id** | **int** | |
|
||||
**symbol** | **str** | |
|
||||
**l1_decimals** | **int** | |
|
||||
**decimals** | **int** | |
|
||||
**min_transfer_amount** | **str** | |
|
||||
**min_withdrawal_amount** | **str** | |
|
||||
**margin_mode** | **str** | |
|
||||
**index_price** | **str** | |
|
||||
**l1_address** | **str** | |
|
||||
|
||||
## Example
|
||||
|
||||
```python
|
||||
from lighter.models.asset import Asset
|
||||
|
||||
# TODO update the JSON string below
|
||||
json = "{}"
|
||||
# create an instance of Asset from a JSON string
|
||||
asset_instance = Asset.from_json(json)
|
||||
# print the JSON string representation of the object
|
||||
print(Asset.to_json())
|
||||
|
||||
# convert the object into a dict
|
||||
asset_dict = asset_instance.to_dict()
|
||||
# create an instance of Asset from a dict
|
||||
asset_from_dict = Asset.from_dict(asset_dict)
|
||||
```
|
||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||
|
||||
|
||||
+9
-10
@@ -1,4 +1,4 @@
|
||||
# PublicPools
|
||||
# AssetDetails
|
||||
|
||||
|
||||
## Properties
|
||||
@@ -7,25 +7,24 @@ Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**code** | **int** | |
|
||||
**message** | **str** | | [optional]
|
||||
**total** | **int** | |
|
||||
**public_pools** | [**List[PublicPool]**](PublicPool.md) | |
|
||||
**asset_details** | [**List[Asset]**](Asset.md) | |
|
||||
|
||||
## Example
|
||||
|
||||
```python
|
||||
from lighter.models.public_pools import PublicPools
|
||||
from lighter.models.asset_details import AssetDetails
|
||||
|
||||
# TODO update the JSON string below
|
||||
json = "{}"
|
||||
# create an instance of PublicPools from a JSON string
|
||||
public_pools_instance = PublicPools.from_json(json)
|
||||
# create an instance of AssetDetails from a JSON string
|
||||
asset_details_instance = AssetDetails.from_json(json)
|
||||
# print the JSON string representation of the object
|
||||
print(PublicPools.to_json())
|
||||
print(AssetDetails.to_json())
|
||||
|
||||
# convert the object into a dict
|
||||
public_pools_dict = public_pools_instance.to_dict()
|
||||
# create an instance of PublicPools from a dict
|
||||
public_pools_from_dict = PublicPools.from_dict(public_pools_dict)
|
||||
asset_details_dict = asset_details_instance.to_dict()
|
||||
# create an instance of AssetDetails from a dict
|
||||
asset_details_from_dict = AssetDetails.from_dict(asset_details_dict)
|
||||
```
|
||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
# Bridge
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**id** | **int** | |
|
||||
**version** | **int** | |
|
||||
**source** | **str** | |
|
||||
**source_chain_id** | **str** | |
|
||||
**fast_bridge_tx_hash** | **str** | |
|
||||
**batch_claim_tx_hash** | **str** | |
|
||||
**cctp_burn_tx_hash** | **str** | |
|
||||
**amount** | **str** | |
|
||||
**intent_address** | **str** | |
|
||||
**status** | **str** | |
|
||||
**step** | **str** | |
|
||||
**description** | **str** | |
|
||||
**created_at** | **int** | |
|
||||
**updated_at** | **int** | |
|
||||
**is_external_deposit** | **bool** | |
|
||||
|
||||
## Example
|
||||
|
||||
```python
|
||||
from lighter.models.bridge import Bridge
|
||||
|
||||
# TODO update the JSON string below
|
||||
json = "{}"
|
||||
# create an instance of Bridge from a JSON string
|
||||
bridge_instance = Bridge.from_json(json)
|
||||
# print the JSON string representation of the object
|
||||
print(Bridge.to_json())
|
||||
|
||||
# convert the object into a dict
|
||||
bridge_dict = bridge_instance.to_dict()
|
||||
# create an instance of Bridge from a dict
|
||||
bridge_from_dict = Bridge.from_dict(bridge_dict)
|
||||
```
|
||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||
|
||||
|
||||
@@ -4,9 +4,149 @@ All URIs are relative to *https://mainnet.zklighter.elliot.ai*
|
||||
|
||||
Method | HTTP request | Description
|
||||
------------- | ------------- | -------------
|
||||
[**bridges**](BridgeApi.md#bridges) | **GET** /api/v1/bridges | bridges
|
||||
[**bridges_is_next_bridge_fast**](BridgeApi.md#bridges_is_next_bridge_fast) | **GET** /api/v1/bridges/isNextBridgeFast | bridges_isNextBridgeFast
|
||||
[**fastbridge_info**](BridgeApi.md#fastbridge_info) | **GET** /api/v1/fastbridge/info | fastbridge_info
|
||||
|
||||
|
||||
# **bridges**
|
||||
> RespGetBridgesByL1Addr bridges(l1_address)
|
||||
|
||||
bridges
|
||||
|
||||
Get bridges for given l1 address
|
||||
|
||||
### Example
|
||||
|
||||
|
||||
```python
|
||||
import lighter
|
||||
from lighter.models.resp_get_bridges_by_l1_addr import RespGetBridgesByL1Addr
|
||||
from lighter.rest import ApiException
|
||||
from pprint import pprint
|
||||
|
||||
# Defining the host is optional and defaults to https://mainnet.zklighter.elliot.ai
|
||||
# See configuration.py for a list of all supported configuration parameters.
|
||||
configuration = lighter.Configuration(
|
||||
host = "https://mainnet.zklighter.elliot.ai"
|
||||
)
|
||||
|
||||
|
||||
# Enter a context with an instance of the API client
|
||||
async with lighter.ApiClient(configuration) as api_client:
|
||||
# Create an instance of the API class
|
||||
api_instance = lighter.BridgeApi(api_client)
|
||||
l1_address = 'l1_address_example' # str |
|
||||
|
||||
try:
|
||||
# bridges
|
||||
api_response = await api_instance.bridges(l1_address)
|
||||
print("The response of BridgeApi->bridges:\n")
|
||||
pprint(api_response)
|
||||
except Exception as e:
|
||||
print("Exception when calling BridgeApi->bridges: %s\n" % e)
|
||||
```
|
||||
|
||||
|
||||
|
||||
### Parameters
|
||||
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------- | ------------- | ------------- | -------------
|
||||
**l1_address** | **str**| |
|
||||
|
||||
### Return type
|
||||
|
||||
[**RespGetBridgesByL1Addr**](RespGetBridgesByL1Addr.md)
|
||||
|
||||
### Authorization
|
||||
|
||||
No authorization required
|
||||
|
||||
### HTTP request headers
|
||||
|
||||
- **Content-Type**: Not defined
|
||||
- **Accept**: application/json
|
||||
|
||||
### HTTP response details
|
||||
|
||||
| Status code | Description | Response headers |
|
||||
|-------------|-------------|------------------|
|
||||
**200** | A successful response. | - |
|
||||
**400** | Bad request | - |
|
||||
|
||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
||||
|
||||
# **bridges_is_next_bridge_fast**
|
||||
> RespGetIsNextBridgeFast bridges_is_next_bridge_fast(l1_address)
|
||||
|
||||
bridges_isNextBridgeFast
|
||||
|
||||
Get if next bridge is fast
|
||||
|
||||
### Example
|
||||
|
||||
|
||||
```python
|
||||
import lighter
|
||||
from lighter.models.resp_get_is_next_bridge_fast import RespGetIsNextBridgeFast
|
||||
from lighter.rest import ApiException
|
||||
from pprint import pprint
|
||||
|
||||
# Defining the host is optional and defaults to https://mainnet.zklighter.elliot.ai
|
||||
# See configuration.py for a list of all supported configuration parameters.
|
||||
configuration = lighter.Configuration(
|
||||
host = "https://mainnet.zklighter.elliot.ai"
|
||||
)
|
||||
|
||||
|
||||
# Enter a context with an instance of the API client
|
||||
async with lighter.ApiClient(configuration) as api_client:
|
||||
# Create an instance of the API class
|
||||
api_instance = lighter.BridgeApi(api_client)
|
||||
l1_address = 'l1_address_example' # str |
|
||||
|
||||
try:
|
||||
# bridges_isNextBridgeFast
|
||||
api_response = await api_instance.bridges_is_next_bridge_fast(l1_address)
|
||||
print("The response of BridgeApi->bridges_is_next_bridge_fast:\n")
|
||||
pprint(api_response)
|
||||
except Exception as e:
|
||||
print("Exception when calling BridgeApi->bridges_is_next_bridge_fast: %s\n" % e)
|
||||
```
|
||||
|
||||
|
||||
|
||||
### Parameters
|
||||
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------- | ------------- | ------------- | -------------
|
||||
**l1_address** | **str**| |
|
||||
|
||||
### Return type
|
||||
|
||||
[**RespGetIsNextBridgeFast**](RespGetIsNextBridgeFast.md)
|
||||
|
||||
### Authorization
|
||||
|
||||
No authorization required
|
||||
|
||||
### HTTP request headers
|
||||
|
||||
- **Content-Type**: Not defined
|
||||
- **Accept**: application/json
|
||||
|
||||
### HTTP response details
|
||||
|
||||
| Status code | Description | Response headers |
|
||||
|-------------|-------------|------------------|
|
||||
**200** | A successful response. | - |
|
||||
**400** | Bad request | - |
|
||||
|
||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
||||
|
||||
# **fastbridge_info**
|
||||
> RespGetFastBridgeInfo fastbridge_info()
|
||||
|
||||
|
||||
@@ -10,6 +10,10 @@ Name | Type | Description | Notes
|
||||
**high** | **float** | |
|
||||
**low** | **float** | |
|
||||
**close** | **float** | |
|
||||
**open_raw** | **float** | |
|
||||
**high_raw** | **float** | |
|
||||
**low_raw** | **float** | |
|
||||
**close_raw** | **float** | |
|
||||
**volume0** | **float** | |
|
||||
**volume1** | **float** | |
|
||||
**last_trade_id** | **int** | |
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**id** | **str** | |
|
||||
**asset_id** | **int** | |
|
||||
**amount** | **str** | |
|
||||
**timestamp** | **int** | |
|
||||
**status** | **str** | |
|
||||
|
||||
@@ -12,7 +12,6 @@ Name | Type | Description | Notes
|
||||
**l1_address** | **str** | |
|
||||
**cancel_all_time** | **int** | |
|
||||
**total_order_count** | **int** | |
|
||||
**total_isolated_order_count** | **int** | |
|
||||
**pending_order_count** | **int** | |
|
||||
**available_balance** | **str** | |
|
||||
**status** | **int** | |
|
||||
@@ -23,6 +22,7 @@ Name | Type | Description | Notes
|
||||
**can_invite** | **bool** | Remove After FE uses L1 meta endpoint |
|
||||
**referral_points_percentage** | **str** | Remove After FE uses L1 meta endpoint |
|
||||
**positions** | [**List[AccountPosition]**](AccountPosition.md) | |
|
||||
**assets** | [**List[AccountAsset]**](AccountAsset.md) | |
|
||||
**total_asset_value** | **str** | |
|
||||
**cross_asset_value** | **str** | |
|
||||
**pool_info** | [**PublicPoolInfo**](PublicPoolInfo.md) | |
|
||||
|
||||
@@ -10,6 +10,10 @@ Name | Type | Description | Notes
|
||||
**high** | **float** | |
|
||||
**low** | **float** | |
|
||||
**close** | **float** | |
|
||||
**open_raw** | **float** | |
|
||||
**high_raw** | **float** | |
|
||||
**low_raw** | **float** | |
|
||||
**close_raw** | **float** | |
|
||||
**volume0** | **float** | |
|
||||
**volume1** | **float** | |
|
||||
**last_trade_id** | **int** | |
|
||||
|
||||
@@ -22,6 +22,7 @@ Name | Type | Description | Notes
|
||||
**executed_at** | **int** | |
|
||||
**sequence_index** | **int** | |
|
||||
**parent_hash** | **str** | |
|
||||
**api_key_index** | **int** | |
|
||||
**committed_at** | **int** | |
|
||||
**verified_at** | **int** | |
|
||||
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
# MarketConfig
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**market_margin_mode** | **int** | |
|
||||
**insurance_fund_account_index** | **int** | |
|
||||
**liquidation_mode** | **int** | |
|
||||
**force_reduce_only** | **bool** | |
|
||||
**trading_hours** | **str** | |
|
||||
|
||||
## Example
|
||||
|
||||
```python
|
||||
from lighter.models.market_config import MarketConfig
|
||||
|
||||
# TODO update the JSON string below
|
||||
json = "{}"
|
||||
# create an instance of MarketConfig from a JSON string
|
||||
market_config_instance = MarketConfig.from_json(json)
|
||||
# print the JSON string representation of the object
|
||||
print(MarketConfig.to_json())
|
||||
|
||||
# convert the object into a dict
|
||||
market_config_dict = market_config_instance.to_dict()
|
||||
# create an instance of MarketConfig from a dict
|
||||
market_config_from_dict = MarketConfig.from_dict(market_config_dict)
|
||||
```
|
||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||
|
||||
|
||||
@@ -36,6 +36,8 @@ Name | Type | Description | Notes
|
||||
**to_cancel_order_id_0** | **str** | |
|
||||
**block_height** | **int** | |
|
||||
**timestamp** | **int** | |
|
||||
**created_at** | **int** | |
|
||||
**updated_at** | **int** | |
|
||||
|
||||
## Example
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ Method | HTTP request | Description
|
||||
------------- | ------------- | -------------
|
||||
[**account_active_orders**](OrderApi.md#account_active_orders) | **GET** /api/v1/accountActiveOrders | accountActiveOrders
|
||||
[**account_inactive_orders**](OrderApi.md#account_inactive_orders) | **GET** /api/v1/accountInactiveOrders | accountInactiveOrders
|
||||
[**asset_details**](OrderApi.md#asset_details) | **GET** /api/v1/assetDetails | assetDetails
|
||||
[**exchange_stats**](OrderApi.md#exchange_stats) | **GET** /api/v1/exchangeStats | exchangeStats
|
||||
[**export**](OrderApi.md#export) | **GET** /api/v1/export | export
|
||||
[**order_book_details**](OrderApi.md#order_book_details) | **GET** /api/v1/orderBookDetails | orderBookDetails
|
||||
@@ -173,6 +174,75 @@ No authorization required
|
||||
|
||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
||||
|
||||
# **asset_details**
|
||||
> AssetDetails asset_details(asset_id=asset_id)
|
||||
|
||||
assetDetails
|
||||
|
||||
Get asset details
|
||||
|
||||
### Example
|
||||
|
||||
|
||||
```python
|
||||
import lighter
|
||||
from lighter.models.asset_details import AssetDetails
|
||||
from lighter.rest import ApiException
|
||||
from pprint import pprint
|
||||
|
||||
# Defining the host is optional and defaults to https://mainnet.zklighter.elliot.ai
|
||||
# See configuration.py for a list of all supported configuration parameters.
|
||||
configuration = lighter.Configuration(
|
||||
host = "https://mainnet.zklighter.elliot.ai"
|
||||
)
|
||||
|
||||
|
||||
# Enter a context with an instance of the API client
|
||||
async with lighter.ApiClient(configuration) as api_client:
|
||||
# Create an instance of the API class
|
||||
api_instance = lighter.OrderApi(api_client)
|
||||
asset_id = 0 # int | (optional) (default to 0)
|
||||
|
||||
try:
|
||||
# assetDetails
|
||||
api_response = await api_instance.asset_details(asset_id=asset_id)
|
||||
print("The response of OrderApi->asset_details:\n")
|
||||
pprint(api_response)
|
||||
except Exception as e:
|
||||
print("Exception when calling OrderApi->asset_details: %s\n" % e)
|
||||
```
|
||||
|
||||
|
||||
|
||||
### Parameters
|
||||
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------- | ------------- | ------------- | -------------
|
||||
**asset_id** | **int**| | [optional] [default to 0]
|
||||
|
||||
### Return type
|
||||
|
||||
[**AssetDetails**](AssetDetails.md)
|
||||
|
||||
### Authorization
|
||||
|
||||
No authorization required
|
||||
|
||||
### HTTP request headers
|
||||
|
||||
- **Content-Type**: Not defined
|
||||
- **Accept**: application/json
|
||||
|
||||
### HTTP response details
|
||||
|
||||
| Status code | Description | Response headers |
|
||||
|-------------|-------------|------------------|
|
||||
**200** | A successful response. | - |
|
||||
**400** | Bad request | - |
|
||||
|
||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
||||
|
||||
# **exchange_stats**
|
||||
> ExchangeStats exchange_stats()
|
||||
|
||||
@@ -316,7 +386,7 @@ No authorization required
|
||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
||||
|
||||
# **order_book_details**
|
||||
> OrderBookDetails order_book_details(market_id=market_id)
|
||||
> OrderBookDetails order_book_details(market_id=market_id, filter=filter)
|
||||
|
||||
orderBookDetails
|
||||
|
||||
@@ -343,10 +413,11 @@ async with lighter.ApiClient(configuration) as api_client:
|
||||
# Create an instance of the API class
|
||||
api_instance = lighter.OrderApi(api_client)
|
||||
market_id = 255 # int | (optional) (default to 255)
|
||||
filter = all # str | (optional) (default to all)
|
||||
|
||||
try:
|
||||
# orderBookDetails
|
||||
api_response = await api_instance.order_book_details(market_id=market_id)
|
||||
api_response = await api_instance.order_book_details(market_id=market_id, filter=filter)
|
||||
print("The response of OrderApi->order_book_details:\n")
|
||||
pprint(api_response)
|
||||
except Exception as e:
|
||||
@@ -361,6 +432,7 @@ async with lighter.ApiClient(configuration) as api_client:
|
||||
Name | Type | Description | Notes
|
||||
------------- | ------------- | ------------- | -------------
|
||||
**market_id** | **int**| | [optional] [default to 255]
|
||||
**filter** | **str**| | [optional] [default to all]
|
||||
|
||||
### Return type
|
||||
|
||||
@@ -456,7 +528,7 @@ No authorization required
|
||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
||||
|
||||
# **order_books**
|
||||
> OrderBooks order_books(market_id=market_id)
|
||||
> OrderBooks order_books(market_id=market_id, filter=filter)
|
||||
|
||||
orderBooks
|
||||
|
||||
@@ -483,10 +555,11 @@ async with lighter.ApiClient(configuration) as api_client:
|
||||
# Create an instance of the API class
|
||||
api_instance = lighter.OrderApi(api_client)
|
||||
market_id = 255 # int | (optional) (default to 255)
|
||||
filter = all # str | (optional) (default to all)
|
||||
|
||||
try:
|
||||
# orderBooks
|
||||
api_response = await api_instance.order_books(market_id=market_id)
|
||||
api_response = await api_instance.order_books(market_id=market_id, filter=filter)
|
||||
print("The response of OrderApi->order_books:\n")
|
||||
pprint(api_response)
|
||||
except Exception as e:
|
||||
@@ -501,6 +574,7 @@ async with lighter.ApiClient(configuration) as api_client:
|
||||
Name | Type | Description | Notes
|
||||
------------- | ------------- | ------------- | -------------
|
||||
**market_id** | **int**| | [optional] [default to 255]
|
||||
**filter** | **str**| | [optional] [default to all]
|
||||
|
||||
### Return type
|
||||
|
||||
@@ -596,7 +670,7 @@ No authorization required
|
||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
||||
|
||||
# **trades**
|
||||
> Trades trades(sort_by, limit, authorization=authorization, auth=auth, market_id=market_id, account_index=account_index, order_index=order_index, sort_dir=sort_dir, cursor=cursor, var_from=var_from, ask_filter=ask_filter)
|
||||
> Trades trades(sort_by, limit, authorization=authorization, auth=auth, market_id=market_id, account_index=account_index, order_index=order_index, sort_dir=sort_dir, cursor=cursor, var_from=var_from, ask_filter=ask_filter, role=role, type=type, aggregate=aggregate)
|
||||
|
||||
trades
|
||||
|
||||
@@ -633,10 +707,13 @@ async with lighter.ApiClient(configuration) as api_client:
|
||||
cursor = 'cursor_example' # str | (optional)
|
||||
var_from = -1 # int | (optional) (default to -1)
|
||||
ask_filter = -1 # int | (optional) (default to -1)
|
||||
role = all # str | (optional) (default to all)
|
||||
type = all # str | (optional) (default to all)
|
||||
aggregate = False # bool | (optional) (default to False)
|
||||
|
||||
try:
|
||||
# trades
|
||||
api_response = await api_instance.trades(sort_by, limit, authorization=authorization, auth=auth, market_id=market_id, account_index=account_index, order_index=order_index, sort_dir=sort_dir, cursor=cursor, var_from=var_from, ask_filter=ask_filter)
|
||||
api_response = await api_instance.trades(sort_by, limit, authorization=authorization, auth=auth, market_id=market_id, account_index=account_index, order_index=order_index, sort_dir=sort_dir, cursor=cursor, var_from=var_from, ask_filter=ask_filter, role=role, type=type, aggregate=aggregate)
|
||||
print("The response of OrderApi->trades:\n")
|
||||
pprint(api_response)
|
||||
except Exception as e:
|
||||
@@ -661,6 +738,9 @@ Name | Type | Description | Notes
|
||||
**cursor** | **str**| | [optional]
|
||||
**var_from** | **int**| | [optional] [default to -1]
|
||||
**ask_filter** | **int**| | [optional] [default to -1]
|
||||
**role** | **str**| | [optional] [default to all]
|
||||
**type** | **str**| | [optional] [default to all]
|
||||
**aggregate** | **bool**| | [optional] [default to False]
|
||||
|
||||
### Return type
|
||||
|
||||
|
||||
@@ -7,12 +7,16 @@ Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**symbol** | **str** | |
|
||||
**market_id** | **int** | |
|
||||
**market_type** | **str** | |
|
||||
**base_asset_id** | **int** | |
|
||||
**quote_asset_id** | **int** | |
|
||||
**status** | **str** | |
|
||||
**taker_fee** | **str** | |
|
||||
**maker_fee** | **str** | |
|
||||
**liquidation_fee** | **str** | |
|
||||
**min_base_amount** | **str** | |
|
||||
**min_quote_amount** | **str** | |
|
||||
**order_quote_limit** | **str** | |
|
||||
**supported_size_decimals** | **int** | |
|
||||
**supported_price_decimals** | **int** | |
|
||||
**supported_quote_decimals** | **int** | |
|
||||
|
||||
@@ -10,6 +10,7 @@ Name | Type | Description | Notes
|
||||
**asks** | [**List[PriceLevel]**](PriceLevel.md) | |
|
||||
**bids** | [**List[PriceLevel]**](PriceLevel.md) | |
|
||||
**offset** | **int** | |
|
||||
**nonce** | **int** | |
|
||||
|
||||
## Example
|
||||
|
||||
|
||||
@@ -7,7 +7,8 @@ Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**code** | **int** | |
|
||||
**message** | **str** | | [optional]
|
||||
**order_book_details** | [**List[OrderBookDetail]**](OrderBookDetail.md) | |
|
||||
**order_book_details** | [**List[PerpsOrderBookDetail]**](PerpsOrderBookDetail.md) | |
|
||||
**spot_order_book_details** | [**List[SpotOrderBookDetail]**](SpotOrderBookDetail.md) | |
|
||||
|
||||
## Example
|
||||
|
||||
|
||||
+12
-8
@@ -1,14 +1,18 @@
|
||||
# MarketInfo
|
||||
# PerpsMarketStats
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**symbol** | **str** | |
|
||||
**market_id** | **int** | |
|
||||
**index_price** | **str** | |
|
||||
**mark_price** | **str** | |
|
||||
**open_interest** | **str** | |
|
||||
**open_interest_limit** | **str** | |
|
||||
**funding_clamp_small** | **str** | |
|
||||
**funding_clamp_big** | **str** | |
|
||||
**last_trade_price** | **str** | |
|
||||
**current_funding_rate** | **str** | |
|
||||
**funding_rate** | **str** | |
|
||||
@@ -22,19 +26,19 @@ Name | Type | Description | Notes
|
||||
## Example
|
||||
|
||||
```python
|
||||
from lighter.models.market_info import MarketInfo
|
||||
from lighter.models.perps_market_stats import PerpsMarketStats
|
||||
|
||||
# TODO update the JSON string below
|
||||
json = "{}"
|
||||
# create an instance of MarketInfo from a JSON string
|
||||
market_info_instance = MarketInfo.from_json(json)
|
||||
# create an instance of PerpsMarketStats from a JSON string
|
||||
perps_market_stats_instance = PerpsMarketStats.from_json(json)
|
||||
# print the JSON string representation of the object
|
||||
print(MarketInfo.to_json())
|
||||
print(PerpsMarketStats.to_json())
|
||||
|
||||
# convert the object into a dict
|
||||
market_info_dict = market_info_instance.to_dict()
|
||||
# create an instance of MarketInfo from a dict
|
||||
market_info_from_dict = MarketInfo.from_dict(market_info_dict)
|
||||
perps_market_stats_dict = perps_market_stats_instance.to_dict()
|
||||
# create an instance of PerpsMarketStats from a dict
|
||||
perps_market_stats_from_dict = PerpsMarketStats.from_dict(perps_market_stats_dict)
|
||||
```
|
||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||
|
||||
+13
-8
@@ -1,4 +1,4 @@
|
||||
# OrderBookDetail
|
||||
# PerpsOrderBookDetail
|
||||
|
||||
|
||||
## Properties
|
||||
@@ -7,12 +7,16 @@ Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**symbol** | **str** | |
|
||||
**market_id** | **int** | |
|
||||
**market_type** | **str** | |
|
||||
**base_asset_id** | **int** | |
|
||||
**quote_asset_id** | **int** | |
|
||||
**status** | **str** | |
|
||||
**taker_fee** | **str** | |
|
||||
**maker_fee** | **str** | |
|
||||
**liquidation_fee** | **str** | |
|
||||
**min_base_amount** | **str** | |
|
||||
**min_quote_amount** | **str** | |
|
||||
**order_quote_limit** | **str** | |
|
||||
**supported_size_decimals** | **int** | |
|
||||
**supported_price_decimals** | **int** | |
|
||||
**supported_quote_decimals** | **int** | |
|
||||
@@ -32,23 +36,24 @@ Name | Type | Description | Notes
|
||||
**daily_price_change** | **float** | |
|
||||
**open_interest** | **float** | |
|
||||
**daily_chart** | **Dict[str, float]** | |
|
||||
**market_config** | [**MarketConfig**](MarketConfig.md) | |
|
||||
|
||||
## Example
|
||||
|
||||
```python
|
||||
from lighter.models.order_book_detail import OrderBookDetail
|
||||
from lighter.models.perps_order_book_detail import PerpsOrderBookDetail
|
||||
|
||||
# TODO update the JSON string below
|
||||
json = "{}"
|
||||
# create an instance of OrderBookDetail from a JSON string
|
||||
order_book_detail_instance = OrderBookDetail.from_json(json)
|
||||
# create an instance of PerpsOrderBookDetail from a JSON string
|
||||
perps_order_book_detail_instance = PerpsOrderBookDetail.from_json(json)
|
||||
# print the JSON string representation of the object
|
||||
print(OrderBookDetail.to_json())
|
||||
print(PerpsOrderBookDetail.to_json())
|
||||
|
||||
# convert the object into a dict
|
||||
order_book_detail_dict = order_book_detail_instance.to_dict()
|
||||
# create an instance of OrderBookDetail from a dict
|
||||
order_book_detail_from_dict = OrderBookDetail.from_dict(order_book_detail_dict)
|
||||
perps_order_book_detail_dict = perps_order_book_detail_instance.to_dict()
|
||||
# create an instance of PerpsOrderBookDetail from a dict
|
||||
perps_order_book_detail_from_dict = PerpsOrderBookDetail.from_dict(perps_order_book_detail_dict)
|
||||
```
|
||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||
|
||||
@@ -7,8 +7,11 @@ Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**timestamp** | **int** | |
|
||||
**trade_pnl** | **float** | |
|
||||
**trade_spot_pnl** | **float** | |
|
||||
**inflow** | **float** | |
|
||||
**outflow** | **float** | |
|
||||
**spot_outflow** | **float** | |
|
||||
**spot_inflow** | **float** | |
|
||||
**pool_pnl** | **float** | |
|
||||
**pool_inflow** | **float** | |
|
||||
**pool_outflow** | **float** | |
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
# PublicPool
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**code** | **int** | |
|
||||
**message** | **str** | | [optional]
|
||||
**account_type** | **int** | |
|
||||
**index** | **int** | |
|
||||
**l1_address** | **str** | |
|
||||
**cancel_all_time** | **int** | |
|
||||
**total_order_count** | **int** | |
|
||||
**total_isolated_order_count** | **int** | |
|
||||
**pending_order_count** | **int** | |
|
||||
**available_balance** | **str** | |
|
||||
**status** | **int** | |
|
||||
**collateral** | **str** | |
|
||||
**account_index** | **int** | |
|
||||
**name** | **str** | |
|
||||
**description** | **str** | |
|
||||
**can_invite** | **bool** | Remove After FE uses L1 meta endpoint |
|
||||
**referral_points_percentage** | **str** | Remove After FE uses L1 meta endpoint |
|
||||
**total_asset_value** | **str** | |
|
||||
**cross_asset_value** | **str** | |
|
||||
**pool_info** | [**PublicPoolInfo**](PublicPoolInfo.md) | |
|
||||
**account_share** | [**PublicPoolShare**](PublicPoolShare.md) | | [optional]
|
||||
|
||||
## Example
|
||||
|
||||
```python
|
||||
from lighter.models.public_pool import PublicPool
|
||||
|
||||
# TODO update the JSON string below
|
||||
json = "{}"
|
||||
# create an instance of PublicPool from a JSON string
|
||||
public_pool_instance = PublicPool.from_json(json)
|
||||
# print the JSON string representation of the object
|
||||
print(PublicPool.to_json())
|
||||
|
||||
# convert the object into a dict
|
||||
public_pool_dict = public_pool_instance.to_dict()
|
||||
# create an instance of PublicPool from a dict
|
||||
public_pool_from_dict = PublicPool.from_dict(public_pool_dict)
|
||||
```
|
||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ Name | Type | Description | Notes
|
||||
**total_shares** | **int** | |
|
||||
**operator_shares** | **int** | |
|
||||
**annual_percentage_yield** | **float** | |
|
||||
**sharpe_ratio** | **float** | |
|
||||
**daily_returns** | [**List[DailyReturn]**](DailyReturn.md) | |
|
||||
**share_prices** | [**List[SharePrice]**](SharePrice.md) | |
|
||||
|
||||
|
||||
@@ -8,10 +8,13 @@ Name | Type | Description | Notes
|
||||
**code** | **int** | |
|
||||
**message** | **str** | | [optional]
|
||||
**account_index** | **int** | |
|
||||
**created_at** | **int** | |
|
||||
**master_account_index** | **int** | |
|
||||
**account_type** | **int** | |
|
||||
**name** | **str** | |
|
||||
**l1_address** | **str** | |
|
||||
**annual_percentage_yield** | **float** | |
|
||||
**sharpe_ratio** | **float** | |
|
||||
**status** | **int** | |
|
||||
**operator_fee** | **str** | |
|
||||
**total_asset_value** | **str** | |
|
||||
|
||||
@@ -4,9 +4,86 @@ All URIs are relative to *https://mainnet.zklighter.elliot.ai*
|
||||
|
||||
Method | HTTP request | Description
|
||||
------------- | ------------- | -------------
|
||||
[**referral_kickback_update**](ReferralApi.md#referral_kickback_update) | **POST** /api/v1/referral/kickback/update | referral_kickback_update
|
||||
[**referral_points**](ReferralApi.md#referral_points) | **GET** /api/v1/referral/points | referral_points
|
||||
[**referral_update**](ReferralApi.md#referral_update) | **POST** /api/v1/referral/update | referral_update
|
||||
|
||||
|
||||
# **referral_kickback_update**
|
||||
> RespUpdateKickback referral_kickback_update(account_index, kickback_percentage, authorization=authorization, auth=auth)
|
||||
|
||||
referral_kickback_update
|
||||
|
||||
Update kickback percentage for referral rewards
|
||||
|
||||
### Example
|
||||
|
||||
|
||||
```python
|
||||
import lighter
|
||||
from lighter.models.resp_update_kickback import RespUpdateKickback
|
||||
from lighter.rest import ApiException
|
||||
from pprint import pprint
|
||||
|
||||
# Defining the host is optional and defaults to https://mainnet.zklighter.elliot.ai
|
||||
# See configuration.py for a list of all supported configuration parameters.
|
||||
configuration = lighter.Configuration(
|
||||
host = "https://mainnet.zklighter.elliot.ai"
|
||||
)
|
||||
|
||||
|
||||
# Enter a context with an instance of the API client
|
||||
async with lighter.ApiClient(configuration) as api_client:
|
||||
# Create an instance of the API class
|
||||
api_instance = lighter.ReferralApi(api_client)
|
||||
account_index = 56 # int |
|
||||
kickback_percentage = 3.4 # float |
|
||||
authorization = 'authorization_example' # str | make required after integ is done (optional)
|
||||
auth = 'auth_example' # str | made optional to support header auth clients (optional)
|
||||
|
||||
try:
|
||||
# referral_kickback_update
|
||||
api_response = await api_instance.referral_kickback_update(account_index, kickback_percentage, authorization=authorization, auth=auth)
|
||||
print("The response of ReferralApi->referral_kickback_update:\n")
|
||||
pprint(api_response)
|
||||
except Exception as e:
|
||||
print("Exception when calling ReferralApi->referral_kickback_update: %s\n" % e)
|
||||
```
|
||||
|
||||
|
||||
|
||||
### Parameters
|
||||
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------- | ------------- | ------------- | -------------
|
||||
**account_index** | **int**| |
|
||||
**kickback_percentage** | **float**| |
|
||||
**authorization** | **str**| make required after integ is done | [optional]
|
||||
**auth** | **str**| made optional to support header auth clients | [optional]
|
||||
|
||||
### Return type
|
||||
|
||||
[**RespUpdateKickback**](RespUpdateKickback.md)
|
||||
|
||||
### Authorization
|
||||
|
||||
No authorization required
|
||||
|
||||
### HTTP request headers
|
||||
|
||||
- **Content-Type**: multipart/form-data
|
||||
- **Accept**: application/json
|
||||
|
||||
### HTTP response details
|
||||
|
||||
| Status code | Description | Response headers |
|
||||
|-------------|-------------|------------------|
|
||||
**200** | A successful response. | - |
|
||||
**400** | Bad request | - |
|
||||
|
||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
||||
|
||||
# **referral_points**
|
||||
> ReferralPoints referral_points(account_index, authorization=authorization, auth=auth)
|
||||
|
||||
@@ -80,3 +157,78 @@ No authorization required
|
||||
|
||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
||||
|
||||
# **referral_update**
|
||||
> RespUpdateReferralCode referral_update(account_index, new_referral_code, authorization=authorization, auth=auth)
|
||||
|
||||
referral_update
|
||||
|
||||
Update referral code (allowed once per account)
|
||||
|
||||
### Example
|
||||
|
||||
|
||||
```python
|
||||
import lighter
|
||||
from lighter.models.resp_update_referral_code import RespUpdateReferralCode
|
||||
from lighter.rest import ApiException
|
||||
from pprint import pprint
|
||||
|
||||
# Defining the host is optional and defaults to https://mainnet.zklighter.elliot.ai
|
||||
# See configuration.py for a list of all supported configuration parameters.
|
||||
configuration = lighter.Configuration(
|
||||
host = "https://mainnet.zklighter.elliot.ai"
|
||||
)
|
||||
|
||||
|
||||
# Enter a context with an instance of the API client
|
||||
async with lighter.ApiClient(configuration) as api_client:
|
||||
# Create an instance of the API class
|
||||
api_instance = lighter.ReferralApi(api_client)
|
||||
account_index = 56 # int |
|
||||
new_referral_code = 'new_referral_code_example' # str |
|
||||
authorization = 'authorization_example' # str | make required after integ is done (optional)
|
||||
auth = 'auth_example' # str | made optional to support header auth clients (optional)
|
||||
|
||||
try:
|
||||
# referral_update
|
||||
api_response = await api_instance.referral_update(account_index, new_referral_code, authorization=authorization, auth=auth)
|
||||
print("The response of ReferralApi->referral_update:\n")
|
||||
pprint(api_response)
|
||||
except Exception as e:
|
||||
print("Exception when calling ReferralApi->referral_update: %s\n" % e)
|
||||
```
|
||||
|
||||
|
||||
|
||||
### Parameters
|
||||
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------- | ------------- | ------------- | -------------
|
||||
**account_index** | **int**| |
|
||||
**new_referral_code** | **str**| |
|
||||
**authorization** | **str**| make required after integ is done | [optional]
|
||||
**auth** | **str**| made optional to support header auth clients | [optional]
|
||||
|
||||
### Return type
|
||||
|
||||
[**RespUpdateReferralCode**](RespUpdateReferralCode.md)
|
||||
|
||||
### Authorization
|
||||
|
||||
No authorization required
|
||||
|
||||
### HTTP request headers
|
||||
|
||||
- **Content-Type**: multipart/form-data
|
||||
- **Accept**: application/json
|
||||
|
||||
### HTTP response details
|
||||
|
||||
| Status code | Description | Response headers |
|
||||
|-------------|-------------|------------------|
|
||||
**200** | A successful response. | - |
|
||||
**400** | Bad request | - |
|
||||
|
||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
||||
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**l1_address** | **str** | |
|
||||
**total_points** | **int** | |
|
||||
**week_points** | **int** | |
|
||||
**total_reward_points** | **int** | |
|
||||
**week_reward_points** | **int** | |
|
||||
**total_points** | **float** | |
|
||||
**week_points** | **float** | |
|
||||
**total_reward_points** | **float** | |
|
||||
**week_reward_points** | **float** | |
|
||||
**reward_point_multiplier** | **str** | |
|
||||
|
||||
## Example
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**referrals** | [**List[ReferralPointEntry]**](ReferralPointEntry.md) | |
|
||||
**user_total_points** | **int** | |
|
||||
**user_last_week_points** | **int** | |
|
||||
**user_total_referral_reward_points** | **int** | |
|
||||
**user_last_week_referral_reward_points** | **int** | |
|
||||
**user_total_points** | **float** | |
|
||||
**user_last_week_points** | **float** | |
|
||||
**user_total_referral_reward_points** | **float** | |
|
||||
**user_last_week_referral_reward_points** | **float** | |
|
||||
**reward_point_multiplier** | **str** | |
|
||||
|
||||
## Example
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
# ReqGetAssetDetails
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**asset_id** | **int** | | [optional]
|
||||
|
||||
## Example
|
||||
|
||||
```python
|
||||
from lighter.models.req_get_asset_details import ReqGetAssetDetails
|
||||
|
||||
# TODO update the JSON string below
|
||||
json = "{}"
|
||||
# create an instance of ReqGetAssetDetails from a JSON string
|
||||
req_get_asset_details_instance = ReqGetAssetDetails.from_json(json)
|
||||
# print the JSON string representation of the object
|
||||
print(ReqGetAssetDetails.to_json())
|
||||
|
||||
# convert the object into a dict
|
||||
req_get_asset_details_dict = req_get_asset_details_instance.to_dict()
|
||||
# create an instance of ReqGetAssetDetails from a dict
|
||||
req_get_asset_details_from_dict = ReqGetAssetDetails.from_dict(req_get_asset_details_dict)
|
||||
```
|
||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
# ReqGetBridgesByL1Addr
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**l1_address** | **str** | |
|
||||
|
||||
## Example
|
||||
|
||||
```python
|
||||
from lighter.models.req_get_bridges_by_l1_addr import ReqGetBridgesByL1Addr
|
||||
|
||||
# TODO update the JSON string below
|
||||
json = "{}"
|
||||
# create an instance of ReqGetBridgesByL1Addr from a JSON string
|
||||
req_get_bridges_by_l1_addr_instance = ReqGetBridgesByL1Addr.from_json(json)
|
||||
# print the JSON string representation of the object
|
||||
print(ReqGetBridgesByL1Addr.to_json())
|
||||
|
||||
# convert the object into a dict
|
||||
req_get_bridges_by_l1_addr_dict = req_get_bridges_by_l1_addr_instance.to_dict()
|
||||
# create an instance of ReqGetBridgesByL1Addr from a dict
|
||||
req_get_bridges_by_l1_addr_from_dict = ReqGetBridgesByL1Addr.from_dict(req_get_bridges_by_l1_addr_dict)
|
||||
```
|
||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**market_id** | **int** | | [optional]
|
||||
**filter** | **str** | | [optional] [default to 'all']
|
||||
|
||||
## Example
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**market_id** | **int** | | [optional]
|
||||
**filter** | **str** | | [optional] [default to 'all']
|
||||
|
||||
## Example
|
||||
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
# ReqGetPublicPools
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**auth** | **str** | | [optional]
|
||||
**filter** | **str** | | [optional]
|
||||
**index** | **int** | |
|
||||
**limit** | **int** | |
|
||||
**account_index** | **int** | | [optional]
|
||||
|
||||
## Example
|
||||
|
||||
```python
|
||||
from lighter.models.req_get_public_pools import ReqGetPublicPools
|
||||
|
||||
# TODO update the JSON string below
|
||||
json = "{}"
|
||||
# create an instance of ReqGetPublicPools from a JSON string
|
||||
req_get_public_pools_instance = ReqGetPublicPools.from_json(json)
|
||||
# print the JSON string representation of the object
|
||||
print(ReqGetPublicPools.to_json())
|
||||
|
||||
# convert the object into a dict
|
||||
req_get_public_pools_dict = req_get_public_pools_instance.to_dict()
|
||||
# create an instance of ReqGetPublicPools from a dict
|
||||
req_get_public_pools_from_dict = ReqGetPublicPools.from_dict(req_get_public_pools_dict)
|
||||
```
|
||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||
|
||||
|
||||
@@ -14,7 +14,10 @@ Name | Type | Description | Notes
|
||||
**cursor** | **str** | | [optional]
|
||||
**var_from** | **int** | | [optional] [default to -1]
|
||||
**ask_filter** | **int** | | [optional]
|
||||
**role** | **str** | | [optional] [default to 'all']
|
||||
**type** | **str** | | [optional] [default to 'all']
|
||||
**limit** | **int** | |
|
||||
**aggregate** | **bool** | | [optional] [default to False]
|
||||
|
||||
## Example
|
||||
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
# RespGetBridgesByL1Addr
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**code** | **int** | |
|
||||
**message** | **str** | | [optional]
|
||||
**bridges** | [**List[Bridge]**](Bridge.md) | |
|
||||
|
||||
## Example
|
||||
|
||||
```python
|
||||
from lighter.models.resp_get_bridges_by_l1_addr import RespGetBridgesByL1Addr
|
||||
|
||||
# TODO update the JSON string below
|
||||
json = "{}"
|
||||
# create an instance of RespGetBridgesByL1Addr from a JSON string
|
||||
resp_get_bridges_by_l1_addr_instance = RespGetBridgesByL1Addr.from_json(json)
|
||||
# print the JSON string representation of the object
|
||||
print(RespGetBridgesByL1Addr.to_json())
|
||||
|
||||
# convert the object into a dict
|
||||
resp_get_bridges_by_l1_addr_dict = resp_get_bridges_by_l1_addr_instance.to_dict()
|
||||
# create an instance of RespGetBridgesByL1Addr from a dict
|
||||
resp_get_bridges_by_l1_addr_from_dict = RespGetBridgesByL1Addr.from_dict(resp_get_bridges_by_l1_addr_dict)
|
||||
```
|
||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
# RespGetIsNextBridgeFast
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**code** | **int** | |
|
||||
**message** | **str** | | [optional]
|
||||
**is_next_bridge_fast** | **bool** | |
|
||||
|
||||
## Example
|
||||
|
||||
```python
|
||||
from lighter.models.resp_get_is_next_bridge_fast import RespGetIsNextBridgeFast
|
||||
|
||||
# TODO update the JSON string below
|
||||
json = "{}"
|
||||
# create an instance of RespGetIsNextBridgeFast from a JSON string
|
||||
resp_get_is_next_bridge_fast_instance = RespGetIsNextBridgeFast.from_json(json)
|
||||
# print the JSON string representation of the object
|
||||
print(RespGetIsNextBridgeFast.to_json())
|
||||
|
||||
# convert the object into a dict
|
||||
resp_get_is_next_bridge_fast_dict = resp_get_is_next_bridge_fast_instance.to_dict()
|
||||
# create an instance of RespGetIsNextBridgeFast from a dict
|
||||
resp_get_is_next_bridge_fast_from_dict = RespGetIsNextBridgeFast.from_dict(resp_get_is_next_bridge_fast_dict)
|
||||
```
|
||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ Name | Type | Description | Notes
|
||||
**message** | **str** | | [optional]
|
||||
**tx_hash** | **str** | |
|
||||
**predicted_execution_time_ms** | **int** | |
|
||||
**volume_quota_remaining** | **int** | |
|
||||
|
||||
## Example
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ Name | Type | Description | Notes
|
||||
**message** | **str** | | [optional]
|
||||
**tx_hash** | **List[str]** | |
|
||||
**predicted_execution_time_ms** | **int** | |
|
||||
**volume_quota_remaining** | **int** | |
|
||||
|
||||
## Example
|
||||
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
# RespUpdateKickback
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**code** | **int** | |
|
||||
**message** | **str** | | [optional]
|
||||
**success** | **bool** | |
|
||||
|
||||
## Example
|
||||
|
||||
```python
|
||||
from lighter.models.resp_update_kickback import RespUpdateKickback
|
||||
|
||||
# TODO update the JSON string below
|
||||
json = "{}"
|
||||
# create an instance of RespUpdateKickback from a JSON string
|
||||
resp_update_kickback_instance = RespUpdateKickback.from_json(json)
|
||||
# print the JSON string representation of the object
|
||||
print(RespUpdateKickback.to_json())
|
||||
|
||||
# convert the object into a dict
|
||||
resp_update_kickback_dict = resp_update_kickback_instance.to_dict()
|
||||
# create an instance of RespUpdateKickback from a dict
|
||||
resp_update_kickback_from_dict = RespUpdateKickback.from_dict(resp_update_kickback_dict)
|
||||
```
|
||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
# RespUpdateReferralCode
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**code** | **int** | |
|
||||
**message** | **str** | | [optional]
|
||||
**success** | **bool** | |
|
||||
|
||||
## Example
|
||||
|
||||
```python
|
||||
from lighter.models.resp_update_referral_code import RespUpdateReferralCode
|
||||
|
||||
# TODO update the JSON string below
|
||||
json = "{}"
|
||||
# create an instance of RespUpdateReferralCode from a JSON string
|
||||
resp_update_referral_code_instance = RespUpdateReferralCode.from_json(json)
|
||||
# print the JSON string representation of the object
|
||||
print(RespUpdateReferralCode.to_json())
|
||||
|
||||
# convert the object into a dict
|
||||
resp_update_referral_code_dict = resp_update_referral_code_instance.to_dict()
|
||||
# create an instance of RespUpdateReferralCode from a dict
|
||||
resp_update_referral_code_from_dict = RespUpdateReferralCode.from_dict(resp_update_referral_code_dict)
|
||||
```
|
||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
# SpotMarketStats
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**symbol** | **str** | |
|
||||
**market_id** | **int** | |
|
||||
**index_price** | **str** | |
|
||||
**mid_price** | **str** | |
|
||||
**last_trade_price** | **str** | |
|
||||
**daily_base_token_volume** | **float** | |
|
||||
**daily_quote_token_volume** | **float** | |
|
||||
**daily_price_low** | **float** | |
|
||||
**daily_price_high** | **float** | |
|
||||
**daily_price_change** | **float** | |
|
||||
|
||||
## Example
|
||||
|
||||
```python
|
||||
from lighter.models.spot_market_stats import SpotMarketStats
|
||||
|
||||
# TODO update the JSON string below
|
||||
json = "{}"
|
||||
# create an instance of SpotMarketStats from a JSON string
|
||||
spot_market_stats_instance = SpotMarketStats.from_json(json)
|
||||
# print the JSON string representation of the object
|
||||
print(SpotMarketStats.to_json())
|
||||
|
||||
# convert the object into a dict
|
||||
spot_market_stats_dict = spot_market_stats_instance.to_dict()
|
||||
# create an instance of SpotMarketStats from a dict
|
||||
spot_market_stats_from_dict = SpotMarketStats.from_dict(spot_market_stats_dict)
|
||||
```
|
||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
# SpotOrderBookDetail
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**symbol** | **str** | |
|
||||
**market_id** | **int** | |
|
||||
**market_type** | **str** | |
|
||||
**base_asset_id** | **int** | |
|
||||
**quote_asset_id** | **int** | |
|
||||
**status** | **str** | |
|
||||
**taker_fee** | **str** | |
|
||||
**maker_fee** | **str** | |
|
||||
**liquidation_fee** | **str** | |
|
||||
**min_base_amount** | **str** | |
|
||||
**min_quote_amount** | **str** | |
|
||||
**order_quote_limit** | **str** | |
|
||||
**supported_size_decimals** | **int** | |
|
||||
**supported_price_decimals** | **int** | |
|
||||
**supported_quote_decimals** | **int** | |
|
||||
**size_decimals** | **int** | |
|
||||
**price_decimals** | **int** | |
|
||||
**last_trade_price** | **float** | |
|
||||
**daily_trades_count** | **int** | |
|
||||
**daily_base_token_volume** | **float** | |
|
||||
**daily_quote_token_volume** | **float** | |
|
||||
**daily_price_low** | **float** | |
|
||||
**daily_price_high** | **float** | |
|
||||
**daily_price_change** | **float** | |
|
||||
**daily_chart** | **Dict[str, float]** | |
|
||||
|
||||
## Example
|
||||
|
||||
```python
|
||||
from lighter.models.spot_order_book_detail import SpotOrderBookDetail
|
||||
|
||||
# TODO update the JSON string below
|
||||
json = "{}"
|
||||
# create an instance of SpotOrderBookDetail from a JSON string
|
||||
spot_order_book_detail_instance = SpotOrderBookDetail.from_json(json)
|
||||
# print the JSON string representation of the object
|
||||
print(SpotOrderBookDetail.to_json())
|
||||
|
||||
# convert the object into a dict
|
||||
spot_order_book_detail_dict = spot_order_book_detail_instance.to_dict()
|
||||
# create an instance of SpotOrderBookDetail from a dict
|
||||
spot_order_book_detail_from_dict = SpotOrderBookDetail.from_dict(spot_order_book_detail_dict)
|
||||
```
|
||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||
|
||||
|
||||
@@ -14,6 +14,8 @@ Name | Type | Description | Notes
|
||||
**usd_amount** | **str** | |
|
||||
**ask_id** | **int** | |
|
||||
**bid_id** | **int** | |
|
||||
**ask_client_id** | **int** | |
|
||||
**bid_client_id** | **int** | |
|
||||
**ask_account_id** | **int** | |
|
||||
**bid_account_id** | **int** | |
|
||||
**is_maker_ask** | **bool** | |
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**id** | **str** | |
|
||||
**asset_id** | **int** | |
|
||||
**amount** | **str** | |
|
||||
**timestamp** | **int** | |
|
||||
**type** | **str** | |
|
||||
@@ -13,6 +14,8 @@ Name | Type | Description | Notes
|
||||
**to_l1_address** | **str** | |
|
||||
**from_account_index** | **int** | |
|
||||
**to_account_index** | **int** | |
|
||||
**from_route** | **str** | |
|
||||
**to_route** | **str** | |
|
||||
**tx_hash** | **str** | |
|
||||
|
||||
## Example
|
||||
|
||||
@@ -20,6 +20,7 @@ Name | Type | Description | Notes
|
||||
**executed_at** | **int** | |
|
||||
**sequence_index** | **int** | |
|
||||
**parent_hash** | **str** | |
|
||||
**api_key_index** | **int** | |
|
||||
|
||||
## Example
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**id** | **str** | |
|
||||
**asset_id** | **int** | |
|
||||
**amount** | **str** | |
|
||||
**timestamp** | **int** | |
|
||||
**status** | **str** | |
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
api_key_config.json
|
||||
@@ -5,18 +5,152 @@
|
||||
- this will require you to enter your Ethereum private key
|
||||
- the eth private key will only be used in the Py SDK to sign a message
|
||||
- the eth private key is not required in order to trade on the platform
|
||||
- the eth private key is not passed to the binary
|
||||
- copy the output of the script and post it into `create_cancel_order.py`
|
||||
- the output should look like
|
||||
```
|
||||
BASE_URL = 'https://testnet.zklighter.elliot.ai'
|
||||
API_KEY_PRIVATE_KEY = '0xea5d2eca5be67eca056752eaf27b173518b8a5550117c09d2b58c7ea7d306cc4426f913ccf27ab19'
|
||||
ACCOUNT_INDEX = 595
|
||||
API_KEY_INDEX = 1
|
||||
```
|
||||
- start trading using
|
||||
- `create_cancel_order.py` has an example which created an order on testnet & cancels it
|
||||
- you'll need to set up both your account index, api key index & API Key private key
|
||||
- the eth private key is not passed to the binary
|
||||
- the API key config is saved in a local file `./api_key_config.json`
|
||||
|
||||
## Start trading on testnet
|
||||
- `create_modify_cancel_order_http.py`
|
||||
- creates an ask (sell) order for 0.1 ETH @ $4050
|
||||
- modified the order and increases the size to 0.11 ETH and increases the price to $4100
|
||||
- cancels the order
|
||||
- Note: all of these operations use the client order index of the order. You can use the order from the exchange as well
|
||||
|
||||
- `create_modify_cancel_order_ws.py`
|
||||
- same flow as `create_modify_cancel_order_http.py`
|
||||
- sends TXs over WS instead of HTTP
|
||||
|
||||
- `create_market_order_eth_buy.py`
|
||||
- creates a market buy order for 0.1 ETH @ market price
|
||||
- `create_market_order_eth_sell.py`
|
||||
- creates a market sell order for 0.1 ETH @ market price
|
||||
|
||||
- `create_grouped_ioc_with_attached_sl_tp.py`
|
||||
- creates an ask (sell) IoC order for 0.1 ETH
|
||||
- along w/ the order, it sets up a Stop Loss (SL) and a Take Profit (TP) order for the whole size of the order
|
||||
- the size of the SL/TP will be equal to the executed size of the order
|
||||
- the SL/TP orders are canceled when the sign of your position changes
|
||||
|
||||
- `create_position_tied_sl_tp.py`
|
||||
- creates a bid (buy) Stop Loss (SL) and a Take Profit (TP) to close your short position
|
||||
- the size of the orders will be for your whole position (because BaseAmount=0)
|
||||
- the orders will grow / shrink as you accumulate more position
|
||||
- the SL/TP orders are canceled when the sign of your position changes
|
||||
|
||||
## On SL/TP orders
|
||||
SL/TP orders need to be configured beyond just setting the trigger price. When the trigger price is set,
|
||||
the order will just be executed, like a normal order. This means that a market order, for example, might not have enough slippage! \
|
||||
Let's say that you have a 1 BTC long position, and the current price is $110'000. \
|
||||
You want to set up a take profit at $120'000
|
||||
- order should be an ask (sell) order, to close your position
|
||||
- the trigger price should be $120'000
|
||||
|
||||
What about the order types? Just as normal orders, SL/TP orders trigger an order, which can be:
|
||||
- market order
|
||||
- limit IOC / GTC
|
||||
|
||||
## Modify leverage / Margin Mode (Cross, Isolated) / Add Collateral to isolated-only positions
|
||||
- `margin_eth_20x_cross_http`
|
||||
- sets ETH market to 20x leverage and cross-margin mode, using HTTP
|
||||
- `margin_eth_50x_isolate_ws`
|
||||
- sets ETH market to 50x leverage and isolated margin mode, using HTTP
|
||||
- `margin_eth_add_collateral_http.py`
|
||||
- adds $10.5 USDC to the ETH position (must be opened and in isolated mode)
|
||||
- `margin_eth_remove_collateral_ws.py`
|
||||
- removes $5 USDC from the ETH position (must be opened and in isolated mode)
|
||||
|
||||
## Batch orders
|
||||
- `send_batch_tx_http.py`
|
||||
- sends multiple orders in a single HTTP request
|
||||
- `send_batch_tx_ws.py`
|
||||
- sends multiple orders in a single WS request`
|
||||
|
||||
Batch TXs will be executed back to back, without the possibility of other TXs interfering.
|
||||
|
||||
## Spot Trading
|
||||
To trade spot markets, you need to have spot USDC. USDC used in your perpetual account will be used as collateral for your cross-positions.
|
||||
USDC deposited in the spot account can only be used to buy spot assets.
|
||||
To transfer USDC between spot <> perp balance, or vice verse, check out
|
||||
- `spot_self_transfer_perp_spot.py`
|
||||
- `spot_self_transfer_spot_perp.py`
|
||||
|
||||
Order placement / trades work in the same way as for perpetual markets.
|
||||
The fee will be paid in the received asset for premium spot trades.
|
||||
This means that if you sell ETH, you'll receive less USDC, and if you BUY 1 ETH, you'll receive slightly less than 1 ETH.
|
||||
You can check out the following examples, which should work on spot ETH by changing the market index to 2048 instead of 0.
|
||||
- `create_modify_cancel_order_http.py`
|
||||
- `create_modify_cancel_order_ws.py`
|
||||
- `create_market_order_eth_buy.py`
|
||||
- `create_market_order_eth_sell.py`
|
||||
- `send_batch_tx_http.py`
|
||||
- `send_batch_tx_ws.py`
|
||||
|
||||
Trading setup is very similar to perpetual markets.
|
||||
The only difference is that you'll need to hold USDC / ETH before placing an order.
|
||||
For example, on perp markets you can place an order to short (sell) ETH without having to worry that much.
|
||||
The limitation there would be to have enough available collateral to cover the order.
|
||||
On spot orders, you need to have enough assets in your spot account to cover all open orders.
|
||||
If you want to place two orders, to buy 1000 USDC worth of ETH and 1000 USDC worth of ZK, you'll need to have at least 2000 available USDC.
|
||||
|
||||
You can get the order book details (including symbol and market index) as well as quote asset id (ETH) and base asset id (USDC)
|
||||
by following the example below:
|
||||
- `spot_get_order_books.py`
|
||||
|
||||
Note: you'll need the quote asset id and base asset id to check available balance.
|
||||
Available balance is not locked in open orders.
|
||||
|
||||
To keep track of your spot balance, you can use HTTP calls or a websocket subscription.
|
||||
Examples on how to do this can be found here:
|
||||
- `spot_get_account_assets_http.py`
|
||||
- `spot_get_account_assets_ws.py`
|
||||
|
||||
Moving money to / from subaccounts is possible for spot assets.
|
||||
For USDC, you can move directly from main perp balance to subaccount spot balance, for example.
|
||||
More details can be found in the following example:
|
||||
- `sub_account_create.py`
|
||||
- `sub_account_transfer_eth.py`
|
||||
- `sub_account_transfer_usdc.py`
|
||||
|
||||
## Public Pools
|
||||
Public pools behave just like subaccounts, except that anyone can join them.
|
||||
You can create / modify a public pool using the SDK. Check out the following example:
|
||||
- `public_pool_create_modify.py`
|
||||
|
||||
To create API keys for a public pool, you need to run the setup script but specify the `ACCOUNT_INDEX` to be the one of the public pool.
|
||||
After that, you can trade from the public as from any other account.
|
||||
|
||||
If you want to deposit / withdraw from a public pool, check the following example:
|
||||
- `public_pool_deposit.py`
|
||||
- `public_pool_withdraw.py`
|
||||
|
||||
To get information about pools, check:
|
||||
- `public_pool_info.py`
|
||||
|
||||
## Moving funds around
|
||||
- `withdraw_fast.py`
|
||||
- send USDC directly from Lighter to Arbitrum
|
||||
- `withdraw_normal.py`
|
||||
- send USDC/ETH from Lighter to Ethereum
|
||||
- `transfer.py`
|
||||
- generic example of how to transfer funds between accounts.
|
||||
- same functionality as `sub_account_transfer_eth` and `sub_account_transfer_usdc`
|
||||
|
||||
## Transfer Notes
|
||||
The `memo` field is a user message, and it has to be exactly 32 bytes long. In case of fast withdrawals, you need to specify the recipient in the memo.
|
||||
This is the case since the memo is part of the signature. This way, the recipient is verified.
|
||||
|
||||
When calling `client.transfer`, you pass the amount without needing to worry about the decimals.
|
||||
When calling `client.sign_transfer` on the other hand, you need to specify the decimals and pass an integer.
|
||||
|
||||
The `fee` field can be obtained by calling `info_api.transfer_fee_info(...)`. The field can be passed as it is.
|
||||
Transfers between subaccounts are free for all assets.
|
||||
|
||||
When sending assets, you can specify the source and destination routes.
|
||||
A route is either `perp` or `spot`. You can send USDC directly from your perp balance to another person's spot balance.
|
||||
If you receive USDC in your perp account, it will be instantly used as collateral for open positions.
|
||||
This also allows you to move USDC from your spot balance to your perp balance.
|
||||
Spot assets (like ETH) need to have both the from and to route set to `spot`.
|
||||
You can get all `asset_id`s by following the example below:
|
||||
- `spot_get_order_books.py`
|
||||
|
||||
## Setup steps for mainnet
|
||||
- deposit money on Lighter to create an account first
|
||||
|
||||
@@ -1,70 +0,0 @@
|
||||
import asyncio
|
||||
import logging
|
||||
import lighter
|
||||
|
||||
logging.basicConfig(level=logging.DEBUG)
|
||||
|
||||
# The API_KEY_PRIVATE_KEY provided belongs to a dummy account registered on Testnet.
|
||||
# It was generated using the setup_system.py script, and servers as an example.
|
||||
# Alternatively, you can go to https://app.lighter.xyz/apikeys for mainnet api keys
|
||||
BASE_URL = "https://testnet.zklighter.elliot.ai"
|
||||
API_KEY_PRIVATE_KEY = "0xed636277f3753b6c0275f7a28c2678a7f3a95655e09deaebec15179b50c5da7f903152e50f594f7b"
|
||||
ACCOUNT_INDEX = 65
|
||||
API_KEY_INDEX = 1
|
||||
|
||||
|
||||
def trim_exception(e: Exception) -> str:
|
||||
return str(e).strip().split("\n")[-1]
|
||||
|
||||
|
||||
async def main():
|
||||
api_client = lighter.ApiClient(configuration=lighter.Configuration(host=BASE_URL))
|
||||
|
||||
client = lighter.SignerClient(
|
||||
url=BASE_URL,
|
||||
private_key=API_KEY_PRIVATE_KEY,
|
||||
account_index=ACCOUNT_INDEX,
|
||||
api_key_index=API_KEY_INDEX,
|
||||
)
|
||||
|
||||
err = client.check_client()
|
||||
if err is not None:
|
||||
print(f"CheckClient error: {trim_exception(err)}")
|
||||
return
|
||||
|
||||
# create order
|
||||
tx, tx_hash, err = await client.create_order(
|
||||
market_index=0,
|
||||
client_order_index=123,
|
||||
base_amount=100000,
|
||||
price=405000,
|
||||
is_ask=True,
|
||||
order_type=lighter.SignerClient.ORDER_TYPE_LIMIT,
|
||||
time_in_force=lighter.SignerClient.ORDER_TIME_IN_FORCE_GOOD_TILL_TIME,
|
||||
reduce_only=0,
|
||||
trigger_price=0,
|
||||
)
|
||||
print(f"Create Order {tx=} {tx_hash=} {err=}")
|
||||
if err is not None:
|
||||
raise Exception(err)
|
||||
|
||||
auth, err = client.create_auth_token_with_expiry(lighter.SignerClient.DEFAULT_10_MIN_AUTH_EXPIRY)
|
||||
print(f"{auth=}")
|
||||
if err is not None:
|
||||
raise Exception(err)
|
||||
|
||||
# cancel order
|
||||
tx, tx_hash, err = await client.cancel_order(
|
||||
market_index=0,
|
||||
order_index=123,
|
||||
)
|
||||
print(f"Cancel Order {tx=} {tx_hash=} {err=}")
|
||||
if err is not None:
|
||||
raise Exception(err)
|
||||
|
||||
await client.close()
|
||||
await api_client.close()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
@@ -0,0 +1,69 @@
|
||||
import asyncio
|
||||
from lighter.signer_client import CreateOrderTxReq
|
||||
from utils import default_example_setup
|
||||
|
||||
|
||||
async def main():
|
||||
client, api_client, _ = default_example_setup()
|
||||
|
||||
# Sell some ETH at $2500
|
||||
# The size of the SL/TP orders will be equal to the size of the executed order
|
||||
|
||||
# set SL trigger price at 5000 and limit price at 5050
|
||||
# set TP trigger price at 1500 and limit price at 1550
|
||||
# Note: set the limit price to be higher than the SL/TP trigger price to ensure the order will be filled
|
||||
# If the mark price of ETH reaches 1500, there might be no one willing to sell you ETH at 1500, so trying to buy at 1550 would increase the fill rate
|
||||
|
||||
ioc_order = CreateOrderTxReq(
|
||||
MarketIndex=0,
|
||||
ClientOrderIndex=0,
|
||||
BaseAmount=1000, # 0.1 ETH
|
||||
Price=2500_00, # $2500
|
||||
IsAsk=1, # sell
|
||||
Type=client.ORDER_TYPE_LIMIT,
|
||||
TimeInForce=client.ORDER_TIME_IN_FORCE_IMMEDIATE_OR_CANCEL,
|
||||
ReduceOnly=0,
|
||||
TriggerPrice=0,
|
||||
OrderExpiry=0,
|
||||
)
|
||||
|
||||
# Create a One-Cancels-the-Other grouped order with a take-profit and a stop-loss order
|
||||
take_profit_order = CreateOrderTxReq(
|
||||
MarketIndex=0,
|
||||
ClientOrderIndex=0,
|
||||
BaseAmount=0,
|
||||
Price=1550_00,
|
||||
IsAsk=0,
|
||||
Type=client.ORDER_TYPE_TAKE_PROFIT_LIMIT,
|
||||
TimeInForce=client.ORDER_TIME_IN_FORCE_GOOD_TILL_TIME,
|
||||
ReduceOnly=1,
|
||||
TriggerPrice=1500_00,
|
||||
OrderExpiry=-1,
|
||||
)
|
||||
|
||||
stop_loss_order = CreateOrderTxReq(
|
||||
MarketIndex=0,
|
||||
ClientOrderIndex=0,
|
||||
BaseAmount=0,
|
||||
Price=5050_00,
|
||||
IsAsk=0,
|
||||
Type=client.ORDER_TYPE_STOP_LOSS_LIMIT,
|
||||
TimeInForce=client.ORDER_TIME_IN_FORCE_GOOD_TILL_TIME,
|
||||
ReduceOnly=1,
|
||||
TriggerPrice=5000_00,
|
||||
OrderExpiry=-1,
|
||||
)
|
||||
|
||||
transaction = await client.create_grouped_orders(
|
||||
grouping_type=client.GROUPING_TYPE_ONE_TRIGGERS_A_ONE_CANCELS_THE_OTHER,
|
||||
orders=[ioc_order, take_profit_order, stop_loss_order],
|
||||
)
|
||||
|
||||
print("Create Grouped Order Tx:", transaction)
|
||||
|
||||
await client.close()
|
||||
await api_client.close()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
@@ -1,39 +0,0 @@
|
||||
import asyncio
|
||||
import logging
|
||||
import lighter
|
||||
|
||||
logging.basicConfig(level=logging.DEBUG)
|
||||
|
||||
# The API_KEY_PRIVATE_KEY provided belongs to a dummy account registered on Testnet.
|
||||
# It was generated using the setup_system.py script, and serves as an example.
|
||||
BASE_URL = "https://testnet.zklighter.elliot.ai"
|
||||
API_KEY_PRIVATE_KEY = "0xed636277f3753b6c0275f7a28c2678a7f3a95655e09deaebec15179b50c5da7f903152e50f594f7b"
|
||||
ACCOUNT_INDEX = 65
|
||||
API_KEY_INDEX = 3
|
||||
|
||||
|
||||
def trim_exception(e: Exception) -> str:
|
||||
return str(e).strip().split("\n")[-1]
|
||||
|
||||
|
||||
async def main():
|
||||
client = lighter.SignerClient(
|
||||
url=BASE_URL,
|
||||
private_key=API_KEY_PRIVATE_KEY,
|
||||
account_index=ACCOUNT_INDEX,
|
||||
api_key_index=API_KEY_INDEX,
|
||||
)
|
||||
|
||||
tx = await client.create_market_order(
|
||||
market_index=0,
|
||||
client_order_index=0,
|
||||
base_amount=1000, # 0.1 ETH
|
||||
avg_execution_price=170000, # $1700 -- worst acceptable price for the order
|
||||
is_ask=True,
|
||||
)
|
||||
print("Create Order Tx:", tx)
|
||||
await client.close()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
@@ -0,0 +1,28 @@
|
||||
import asyncio
|
||||
from utils import default_example_setup
|
||||
|
||||
|
||||
async def main():
|
||||
client, api_client, _ = default_example_setup()
|
||||
client.check_client()
|
||||
|
||||
# Note: change this to 2048 to trade spot ETH. Make sure you have at least 0.1 ETH to trade spot.
|
||||
market_index = 0
|
||||
|
||||
tx, tx_hash, err = await client.create_market_order(
|
||||
market_index=market_index,
|
||||
client_order_index=0,
|
||||
base_amount=1000, # 0.1 ETH
|
||||
avg_execution_price=4000_00, # $4000 -- worst acceptable price for the order
|
||||
is_ask=False,
|
||||
)
|
||||
print(f"Create Order {tx=} {tx_hash=} {err=}")
|
||||
if err is not None:
|
||||
raise Exception(err)
|
||||
|
||||
await client.close()
|
||||
await api_client.close()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
@@ -0,0 +1,28 @@
|
||||
import asyncio
|
||||
from utils import default_example_setup
|
||||
|
||||
|
||||
async def main():
|
||||
client, api_client, _ = default_example_setup()
|
||||
client.check_client()
|
||||
|
||||
# Note: change this to 2048 to trade spot ETH. Make sure you have at least 0.1 ETH to trade spot.
|
||||
market_index = 0
|
||||
|
||||
tx, tx_hash, err = await client.create_market_order(
|
||||
market_index=market_index,
|
||||
client_order_index=0,
|
||||
base_amount=1000, # 0.1 ETH
|
||||
avg_execution_price=1700_00, # $1700 -- worst acceptable price for the order
|
||||
is_ask=True,
|
||||
)
|
||||
print(f"Create Order {tx=} {tx_hash=} {err=}")
|
||||
if err is not None:
|
||||
raise Exception(err)
|
||||
|
||||
await client.close()
|
||||
await api_client.close()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
@@ -1,33 +1,21 @@
|
||||
import asyncio
|
||||
import logging
|
||||
import lighter
|
||||
|
||||
logging.basicConfig(level=logging.DEBUG)
|
||||
|
||||
# The API_KEY_PRIVATE_KEY provided belongs to a dummy account registered on Testnet.
|
||||
# It was generated using the setup_system.py script, and serves as an example.
|
||||
BASE_URL = "https://testnet.zklighter.elliot.ai"
|
||||
API_KEY_PRIVATE_KEY = "0xe0fa55e11d6b5575d54c0500bd2f3b240221ae90241e3b573f2307e27de20c04ea628de3f1936e56"
|
||||
ACCOUNT_INDEX = 22
|
||||
API_KEY_INDEX = 3
|
||||
|
||||
|
||||
def trim_exception(e: Exception) -> str:
|
||||
return str(e).strip().split("\n")[-1]
|
||||
from utils import default_example_setup
|
||||
|
||||
|
||||
async def main():
|
||||
client = lighter.SignerClient(
|
||||
url=BASE_URL,
|
||||
private_key=API_KEY_PRIVATE_KEY,
|
||||
account_index=ACCOUNT_INDEX,
|
||||
api_key_index=API_KEY_INDEX,
|
||||
)
|
||||
client, api_client, _ = default_example_setup()
|
||||
|
||||
# tx = await client.create_market_order_limited_slippage(market_index=0, client_order_index=0, base_amount=30000000,
|
||||
# max_slippage=0.001, is_ask=True)
|
||||
tx = await client.create_market_order_if_slippage(market_index=0, client_order_index=0, base_amount=30000000,
|
||||
max_slippage=0.01, is_ask=True, ideal_price=300000)
|
||||
tx = await client.create_market_order_if_slippage(
|
||||
market_index=0, # ETH
|
||||
client_order_index=0,
|
||||
base_amount=1000, # 0.1 ETH
|
||||
max_slippage=0.01, # 1%
|
||||
is_ask=True,
|
||||
ideal_price=300000 # $3000
|
||||
)
|
||||
|
||||
print("Create Order Tx:", tx)
|
||||
await client.close()
|
||||
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
import asyncio
|
||||
from utils import default_example_setup
|
||||
|
||||
|
||||
async def main():
|
||||
client, api_client, _ = default_example_setup()
|
||||
client.check_client()
|
||||
|
||||
# Note: change this to 2048 to trade spot ETH. Make sure you have at least 0.1 ETH to trade spot.
|
||||
market_index = 0
|
||||
|
||||
# create order
|
||||
api_key_index, nonce = client.nonce_manager.next_nonce()
|
||||
tx, tx_hash, err = await client.create_order(
|
||||
market_index=market_index,
|
||||
client_order_index=123,
|
||||
base_amount=1000, # 0.1 ETH
|
||||
price=4050_00, # $4050
|
||||
is_ask=True,
|
||||
order_type=client.ORDER_TYPE_LIMIT,
|
||||
time_in_force=client.ORDER_TIME_IN_FORCE_GOOD_TILL_TIME,
|
||||
reduce_only=False,
|
||||
trigger_price=0,
|
||||
nonce=nonce,
|
||||
api_key_index=api_key_index,
|
||||
)
|
||||
print(f"Create Order {tx=} {tx_hash=} {err=}")
|
||||
if err is not None:
|
||||
raise Exception(err)
|
||||
|
||||
## modify order
|
||||
# use the same API key so the TX goes after the create order TX
|
||||
api_key_index, nonce = client.nonce_manager.next_nonce(api_key_index)
|
||||
tx, tx_hash, err = await client.modify_order(
|
||||
market_index=market_index,
|
||||
order_index=123,
|
||||
base_amount=1100, # 0.11 ETH
|
||||
price=4100_00, # $4100
|
||||
trigger_price=0,
|
||||
nonce=nonce,
|
||||
api_key_index=api_key_index,
|
||||
)
|
||||
print(f"Modify Order {tx=} {tx_hash=} {err=}")
|
||||
if err is not None:
|
||||
raise Exception(err)
|
||||
|
||||
## cancel order
|
||||
# use the same API key so the TX goes after the modify order TX
|
||||
api_key_index, nonce = client.nonce_manager.next_nonce(api_key_index)
|
||||
tx, tx_hash, err = await client.cancel_order(
|
||||
market_index=market_index,
|
||||
order_index=123,
|
||||
nonce=nonce,
|
||||
api_key_index=api_key_index,
|
||||
)
|
||||
print(f"Cancel Order {tx=} {tx_hash=} {err=}")
|
||||
if err is not None:
|
||||
raise Exception(err)
|
||||
|
||||
await client.close()
|
||||
await api_client.close()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
@@ -0,0 +1,72 @@
|
||||
import websockets
|
||||
import asyncio
|
||||
from utils import default_example_setup, ws_send_tx
|
||||
|
||||
|
||||
# this example does the same thing as the create_modify_cancel_order.py example, but sends the TX over WS instead of HTTP
|
||||
async def main():
|
||||
client, api_client, ws_client_promise = default_example_setup()
|
||||
client.check_client()
|
||||
|
||||
# set up WS client and print a connected message
|
||||
ws_client: websockets.ClientConnection = await ws_client_promise
|
||||
print("Received:", await ws_client.recv())
|
||||
|
||||
# Note: change this to 2048 to trade spot ETH. Make sure you have at least 0.1 ETH to trade spot.
|
||||
market_index = 0
|
||||
|
||||
# create order
|
||||
api_key_index, nonce = client.nonce_manager.next_nonce()
|
||||
tx_type, tx_info, tx_hash, err = client.sign_create_order(
|
||||
market_index=market_index,
|
||||
client_order_index=123,
|
||||
base_amount=1000, # 0.1 ETH
|
||||
price=4050_00, # $4050
|
||||
is_ask=True,
|
||||
order_type=client.ORDER_TYPE_LIMIT,
|
||||
time_in_force=client.ORDER_TIME_IN_FORCE_GOOD_TILL_TIME,
|
||||
reduce_only=False,
|
||||
trigger_price=0,
|
||||
nonce=nonce,
|
||||
api_key_index=api_key_index,
|
||||
)
|
||||
if err is not None:
|
||||
raise Exception(err)
|
||||
await ws_send_tx(ws_client, tx_type, tx_info, tx_hash)
|
||||
|
||||
## modify order
|
||||
# use the same API key so the TX goes after the create order TX
|
||||
api_key_index, nonce = client.nonce_manager.next_nonce(api_key_index)
|
||||
tx_type, tx_info, tx_hash, err = client.sign_modify_order(
|
||||
market_index=market_index,
|
||||
order_index=123,
|
||||
base_amount=1100, # 0.11 ETH
|
||||
price=4100_00, # $4100
|
||||
trigger_price=0,
|
||||
nonce=nonce,
|
||||
api_key_index=api_key_index,
|
||||
)
|
||||
if err is not None:
|
||||
raise Exception(err)
|
||||
await ws_send_tx(ws_client, tx_type, tx_info, tx_hash)
|
||||
|
||||
## cancel order
|
||||
# use the same API key so the TX goes after the modify order TX
|
||||
api_key_index, nonce = client.nonce_manager.next_nonce(api_key_index)
|
||||
tx_type, tx_info, tx_hash, err = client.sign_cancel_order(
|
||||
market_index=market_index,
|
||||
order_index=123,
|
||||
nonce=nonce,
|
||||
api_key_index=api_key_index,
|
||||
)
|
||||
if err is not None:
|
||||
raise Exception(err)
|
||||
await ws_send_tx(ws_client, tx_type, tx_info, tx_hash)
|
||||
|
||||
await client.close()
|
||||
await api_client.close()
|
||||
await ws_client.close()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
@@ -0,0 +1,56 @@
|
||||
import asyncio
|
||||
from lighter.signer_client import CreateOrderTxReq
|
||||
from utils import default_example_setup
|
||||
|
||||
|
||||
async def main():
|
||||
client, api_client, _ = default_example_setup()
|
||||
|
||||
# Creates a position tied SL/TP pair
|
||||
# The SL/TP orders will close your whole position, even if you add/remove from it later on
|
||||
# if the positions reach 0 or switches from short -> long, the orders are canceled
|
||||
|
||||
# this particular example, sets the SL/TP for a short position
|
||||
# set SL trigger price at 5000 and limit price at 5050
|
||||
# set TP trigger price at 1500 and limit price at 1550
|
||||
# Note: set the limit price to be higher than the SL/TP trigger price to ensure the order will be filled
|
||||
# If the mark price of ETH reaches 1500, there might be no one willing to sell you ETH at 1500, so trying to buy at 1550 would increase the fill rate
|
||||
|
||||
# Create a One-Cancels-the-Other grouped order with a take-profit and a stop-loss order
|
||||
take_profit_order = CreateOrderTxReq(
|
||||
MarketIndex=0,
|
||||
ClientOrderIndex=0,
|
||||
BaseAmount=0,
|
||||
Price=1550_00,
|
||||
IsAsk=0,
|
||||
Type=client.ORDER_TYPE_TAKE_PROFIT_LIMIT,
|
||||
TimeInForce=client.ORDER_TIME_IN_FORCE_GOOD_TILL_TIME,
|
||||
ReduceOnly=1,
|
||||
TriggerPrice=1500_00,
|
||||
OrderExpiry=-1,
|
||||
)
|
||||
|
||||
stop_loss_order = CreateOrderTxReq(
|
||||
MarketIndex=0,
|
||||
ClientOrderIndex=0,
|
||||
BaseAmount=0,
|
||||
Price=4050_00,
|
||||
IsAsk=0,
|
||||
Type=client.ORDER_TYPE_STOP_LOSS_LIMIT,
|
||||
TimeInForce=client.ORDER_TIME_IN_FORCE_GOOD_TILL_TIME,
|
||||
ReduceOnly=1,
|
||||
TriggerPrice=4000_00,
|
||||
OrderExpiry=-1,
|
||||
)
|
||||
|
||||
transaction = await client.create_grouped_orders(
|
||||
grouping_type=client.GROUPING_TYPE_ONE_CANCELS_THE_OTHER,
|
||||
orders=[take_profit_order, stop_loss_order],
|
||||
)
|
||||
|
||||
print("Create Grouped Order Tx:", transaction)
|
||||
await client.close()
|
||||
await api_client.close()
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
@@ -1,70 +0,0 @@
|
||||
import asyncio
|
||||
import logging
|
||||
import lighter
|
||||
|
||||
logging.basicConfig(level=logging.DEBUG)
|
||||
|
||||
# The API_KEY_PRIVATE_KEY provided belongs to a dummy account registered on Testnet.
|
||||
# It was generated using the setup_system.py script, and servers as an example.
|
||||
BASE_URL = "https://testnet.zklighter.elliot.ai"
|
||||
API_KEY_PRIVATE_KEY = "0xe0fa55e11d6b5575d54c0500bd2f3b240221ae90241e3b573f2307e27de20c04ea628de3f1936e56"
|
||||
ACCOUNT_INDEX = 22
|
||||
API_KEY_INDEX = 3
|
||||
|
||||
|
||||
def trim_exception(e: Exception) -> str:
|
||||
return str(e).strip().split("\n")[-1]
|
||||
|
||||
|
||||
async def main():
|
||||
client = lighter.SignerClient(
|
||||
url=BASE_URL,
|
||||
private_key=API_KEY_PRIVATE_KEY,
|
||||
account_index=ACCOUNT_INDEX,
|
||||
api_key_index=API_KEY_INDEX,
|
||||
)
|
||||
|
||||
tx = await client.create_tp_order(
|
||||
market_index=0,
|
||||
client_order_index=0,
|
||||
base_amount=1000, # 0.1 ETH
|
||||
trigger_price=500000,
|
||||
price=500000,
|
||||
is_ask=False
|
||||
)
|
||||
print("Create Order Tx:", tx)
|
||||
|
||||
|
||||
tx = await client.create_sl_order(
|
||||
market_index=0,
|
||||
client_order_index=0,
|
||||
base_amount=1000, # 0.1 ETH
|
||||
trigger_price=500000,
|
||||
price=500000,
|
||||
is_ask=False
|
||||
)
|
||||
print("Create Order Tx:", tx)
|
||||
|
||||
tx = await client.create_tp_limit_order(
|
||||
market_index=0,
|
||||
client_order_index=0,
|
||||
base_amount=1000, # 0.1 ETH
|
||||
trigger_price=500000,
|
||||
price=500000,
|
||||
is_ask=False
|
||||
)
|
||||
|
||||
tx = await client.create_sl_limit_order(
|
||||
market_index=0,
|
||||
client_order_index=0,
|
||||
base_amount=1000, # 0.1 ETH
|
||||
trigger_price=500000,
|
||||
price=500000,
|
||||
is_ask=False
|
||||
)
|
||||
print("Create Order Tx:", tx)
|
||||
await client.close()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
@@ -1,47 +1,30 @@
|
||||
import time
|
||||
import asyncio
|
||||
import lighter
|
||||
|
||||
|
||||
BASE_URL = "https://testnet.zklighter.elliot.ai"
|
||||
# use examples/system_setup.py or the apikeys page (for mainnet) to generate new api keys
|
||||
KEYS = {
|
||||
5: "API_PRIVATE_KEY_5",
|
||||
6: "API_PRIVATE_KEY_6",
|
||||
7: "API_PRIVATE_KEY_7",
|
||||
}
|
||||
ACCOUNT_INDEX = 100 # replace with your account_index
|
||||
from utils import default_example_setup
|
||||
|
||||
|
||||
async def main():
|
||||
client = lighter.SignerClient(
|
||||
url=BASE_URL,
|
||||
private_key=KEYS[5],
|
||||
account_index=ACCOUNT_INDEX,
|
||||
api_key_index=5,
|
||||
max_api_key_index=7,
|
||||
private_keys=KEYS,
|
||||
)
|
||||
client, api_client, _ = default_example_setup()
|
||||
|
||||
err = client.check_client()
|
||||
if err is not None:
|
||||
print(f"CheckClient error: {err}")
|
||||
return
|
||||
# create 20 orders. The client will use as many API keys as it was configured.
|
||||
|
||||
for i in range(20):
|
||||
res_tuple = await client.create_order(
|
||||
market_index=0,
|
||||
client_order_index=123 + i,
|
||||
base_amount=100000 + i,
|
||||
price=385000 + i,
|
||||
base_amount=1000 + i, # 0.1 ETH + dust
|
||||
price=3850_00 + i,
|
||||
is_ask=True,
|
||||
order_type=lighter.SignerClient.ORDER_TYPE_LIMIT,
|
||||
time_in_force=lighter.SignerClient.ORDER_TIME_IN_FORCE_GOOD_TILL_TIME,
|
||||
reduce_only=0,
|
||||
order_type=client.ORDER_TYPE_LIMIT,
|
||||
time_in_force=client.ORDER_TIME_IN_FORCE_GOOD_TILL_TIME,
|
||||
reduce_only=False,
|
||||
trigger_price=0,
|
||||
)
|
||||
print(res_tuple)
|
||||
|
||||
await client.cancel_all_orders(time_in_force=client.CANCEL_ALL_TIF_IMMEDIATE, time=0)
|
||||
# wait for orders to be created
|
||||
time.sleep(1)
|
||||
await client.cancel_all_orders(time_in_force=client.CANCEL_ALL_TIF_IMMEDIATE, timestamp_ms=0)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -75,7 +75,11 @@ async def transaction_apis(client: lighter.ApiClient):
|
||||
# use with a valid sequence index
|
||||
# await print_api(transaction_instance.tx, by="sequence_index", value="5")
|
||||
await print_api(transaction_instance.txs, index=0, limit=2)
|
||||
|
||||
|
||||
async def funding_apis(client: lighter.ApiClient):
|
||||
logging.info("FUNDING APIS")
|
||||
account_instance = lighter.FundingApi(client)
|
||||
await print_api(account_instance.funding_rates)
|
||||
|
||||
async def main():
|
||||
client = lighter.ApiClient(configuration=lighter.Configuration(host="https://testnet.zklighter.elliot.ai"))
|
||||
@@ -84,6 +88,7 @@ async def main():
|
||||
await candlestick_apis(client)
|
||||
await order_apis(client)
|
||||
await transaction_apis(client)
|
||||
await funding_apis(client)
|
||||
await client.close()
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
import asyncio
|
||||
from utils import default_example_setup
|
||||
|
||||
|
||||
async def main():
|
||||
client, api_client, _ = default_example_setup()
|
||||
|
||||
# Note: the HTTP method `update_leverage` receives `leverage` as the argument,
|
||||
# while the WS one that calls `sign_update_leverage` to get the TX to send it directly over WS
|
||||
# receives `fraction` as the argument, which is 10_000 / leverage
|
||||
# this was kept this way to not break backwards compatibility. Ideally, they would be consistent.
|
||||
|
||||
tx, tx_hash, err = await client.update_leverage(
|
||||
market_index=0,
|
||||
leverage=20,
|
||||
margin_mode=client.CROSS_MARGIN_MODE
|
||||
)
|
||||
|
||||
print(f"Update Leverage {tx=} {tx_hash=} {err=}")
|
||||
if err is not None:
|
||||
raise Exception(err)
|
||||
|
||||
await client.close()
|
||||
await api_client.close()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
import websockets
|
||||
import asyncio
|
||||
from utils import default_example_setup, ws_send_tx
|
||||
|
||||
|
||||
async def main():
|
||||
client, api_client, ws_client_promise = default_example_setup()
|
||||
|
||||
# set up WS client and print a connected message
|
||||
ws_client: websockets.ClientConnection = await ws_client_promise
|
||||
print("Received:", await ws_client.recv())
|
||||
|
||||
# Note: the HTTP method `update_leverage` receives `leverage` as the argument,
|
||||
# while the WS one that calls `sign_update_leverage` to get the TX to send it directly over WS
|
||||
# receives `fraction` as the argument, which is 10_000 / leverage
|
||||
# this was kept this way to not break backwards compatibility. Ideally, they would be consistent.
|
||||
|
||||
tx_type, tx_info, tx_hash, err = client.sign_update_leverage(
|
||||
market_index=0,
|
||||
fraction=10_000 // 50,
|
||||
margin_mode=client.ISOLATED_MARGIN_MODE
|
||||
)
|
||||
if err is not None:
|
||||
raise Exception(err)
|
||||
await ws_send_tx(ws_client, tx_type, tx_info, tx_hash)
|
||||
|
||||
await client.close()
|
||||
await api_client.close()
|
||||
await ws_client.close()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
@@ -0,0 +1,29 @@
|
||||
import asyncio
|
||||
from utils import default_example_setup
|
||||
|
||||
|
||||
async def main():
|
||||
client, api_client, _ = default_example_setup()
|
||||
|
||||
# Note: the HTTP method `update_margin` receives `usdc_amount` (float) as the argument,
|
||||
# while the WS one that calls `sign_update_margin` to get the TX to send it directly over WS
|
||||
# receives `usdc_amount` (int) as the argument, which is the float one * 1_000_000
|
||||
# this was kept this way to not break backwards compatibility. Ideally, they would be consistent.
|
||||
|
||||
tx, tx_hash, err = await client.update_margin(
|
||||
market_index=0,
|
||||
usdc_amount=10.5,
|
||||
direction=client.ISOLATED_MARGIN_ADD_COLLATERAL
|
||||
)
|
||||
|
||||
print(f"Update Margin {tx=} {tx_hash=} {err=}")
|
||||
if err is not None:
|
||||
raise Exception(err)
|
||||
|
||||
await client.close()
|
||||
await api_client.close()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
import asyncio
|
||||
import websockets
|
||||
from utils import default_example_setup, ws_send_tx
|
||||
|
||||
|
||||
async def main():
|
||||
client, api_client, ws_client_promise = default_example_setup()
|
||||
|
||||
# set up WS client and print a connected message
|
||||
ws_client: websockets.ClientConnection = await ws_client_promise
|
||||
print("Received:", await ws_client.recv())
|
||||
|
||||
# Note: the HTTP method `update_margin` receives `usdc_amount` (float) as the argument,
|
||||
# while the WS one that calls `sign_update_margin` to get the TX to send it directly over WS
|
||||
# receives `usdc_amount` (int) as the argument, which is the float one * 1_000_000
|
||||
# this was kept this way to not break backwards compatibility. Ideally, they would be consistent.
|
||||
|
||||
tx_type, tx_info, tx_hash, err = client.sign_update_margin(
|
||||
market_index=0,
|
||||
usdc_amount=5_000_000, # 5 USDC
|
||||
direction=client.ISOLATED_MARGIN_REMOVE_COLLATERAL
|
||||
)
|
||||
if err is not None:
|
||||
raise Exception(err)
|
||||
await ws_send_tx(ws_client, tx_type, tx_info, tx_hash)
|
||||
|
||||
await client.close()
|
||||
await api_client.close()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
@@ -0,0 +1,59 @@
|
||||
import time
|
||||
import json
|
||||
import asyncio
|
||||
import lighter
|
||||
from utils import default_example_setup
|
||||
|
||||
|
||||
async def main():
|
||||
client, api_client, _ = default_example_setup()
|
||||
tx_api = lighter.TransactionApi(api_client)
|
||||
|
||||
err = client.check_client()
|
||||
if err is not None:
|
||||
print(f"CheckClient error: {err}")
|
||||
return
|
||||
|
||||
auth, _ = client.create_auth_token_with_expiry()
|
||||
|
||||
# create a public pool
|
||||
tx_info, response, err = await client.create_public_pool(
|
||||
operator_fee=100000, # 10%
|
||||
initial_total_shares=1_000_000, # 1000 USDC
|
||||
min_operator_share_rate=100, # 1%
|
||||
)
|
||||
if err is not None:
|
||||
raise Exception(f'failed to create public pool {err}')
|
||||
tx_hash = response.tx_hash
|
||||
print(f"✅ send create public pool tx. hash: {tx_hash}")
|
||||
|
||||
# fetch pool account index from tx hash
|
||||
pool_account_index = -1
|
||||
for i in range(10):
|
||||
time.sleep(1)
|
||||
try:
|
||||
response = await tx_api.tx(by="hash", value=tx_hash)
|
||||
event_info_j = json.loads(response.event_info)
|
||||
pool_account_index = event_info_j['a']
|
||||
except Exception as e:
|
||||
pass
|
||||
if pool_account_index != -1:
|
||||
break
|
||||
if pool_account_index == -1:
|
||||
raise Exception(f"failed to find pool account index for tx {tx_hash}")
|
||||
print(f"✅ pool account index: {pool_account_index}")
|
||||
|
||||
# Note: ❗️operator_fee can only decrease
|
||||
# modify pool metadata
|
||||
tx_info, response, err = await client.update_public_pool(
|
||||
public_pool_index=pool_account_index,
|
||||
status=0, # 0 is active | 1 is frozen
|
||||
operator_fee=50000, # 5%
|
||||
min_operator_share_rate=1000, # 10%
|
||||
)
|
||||
if err is not None:
|
||||
raise Exception(f'failed to create update pool {err}')
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
@@ -0,0 +1,25 @@
|
||||
import asyncio
|
||||
|
||||
from utils import default_example_setup
|
||||
|
||||
POOL_ACCOUNT_INDEX = 281474976710651
|
||||
|
||||
|
||||
async def main():
|
||||
client, api_client, _ = default_example_setup()
|
||||
|
||||
err = client.check_client()
|
||||
if err is not None:
|
||||
print(f"CheckClient error: {err}")
|
||||
return
|
||||
|
||||
tx_info, response, err = await client.mint_shares(public_pool_index=POOL_ACCOUNT_INDEX, share_amount=10_000)
|
||||
if err is not None:
|
||||
raise Exception(f'failed to mint shares {err}')
|
||||
|
||||
await client.close()
|
||||
await api_client.close()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
@@ -0,0 +1,33 @@
|
||||
import asyncio
|
||||
import lighter
|
||||
from utils import default_example_setup
|
||||
|
||||
POOL_ACCOUNT_INDEX = 281474976710651
|
||||
|
||||
|
||||
async def main():
|
||||
client, api_client, _ = default_example_setup()
|
||||
account_api = lighter.AccountApi(api_client)
|
||||
|
||||
err = client.check_client()
|
||||
if err is not None:
|
||||
print(f"CheckClient error: {err}")
|
||||
return
|
||||
|
||||
account = await account_api.account(by="index", value=str(client.account_index))
|
||||
|
||||
# Note: ❗️shares field does not return the shared you have in pools that you're the operator
|
||||
for pool in account.accounts[0].shares:
|
||||
pool_resp = await account_api.account(by="index", value=str(pool.public_pool_index))
|
||||
pool_account = pool_resp.accounts[0]
|
||||
|
||||
share_price = float(pool_account.total_asset_value) / float(pool_account.pool_info.total_shares)
|
||||
print(
|
||||
f"poolAccountId: {pool.public_pool_index} numShared: {pool.shares_amount} sharePrice: {share_price:.6f} value: {share_price * pool.shares_amount:.2f} pnl: {share_price * pool.shares_amount - float(pool.entry_usdc):.2f}")
|
||||
|
||||
await client.close()
|
||||
await api_client.close()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user