{"_id":"@dexalot/dexalot-sdk","_rev":"9-49985416bc9b5cf448e105bc05460aef","name":"@dexalot/dexalot-sdk","dist-tags":{"latest":"0.6.2"},"versions":{"0.5.16":{"name":"@dexalot/dexalot-sdk","version":"0.5.16","license":"MIT","_id":"@dexalot/dexalot-sdk@0.5.16","maintainers":[{"name":"ilkerdexalot","email":"ilker@dexalot.com"},{"name":"the_axol0tl","email":"mng@dexalot.com"}],"dist":{"shasum":"1603ae156504e51621d5978bb7a03731f354f210","tarball":"https://registry.npmjs.org/@dexalot/dexalot-sdk/-/dexalot-sdk-0.5.16.tgz","fileCount":192,"integrity":"sha512-WqL0SCrz+sjVozFY0FpuZdmDAY+Tii3bmojv84puyoMAgaDDICzxWaAuoZwe9I2igr8C95M6Cql9sLQ1fR1tXQ==","signatures":[{"sig":"MEYCIQD9BdTGhvbQ0F3smbdbQcot12YZRuffkjdOWEel+QDknAIhAKVk94Yc0lp2Zf5MPmqLruuuGnul01qDaeuNe5RL8bbe","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1905890},"main":"dist/index.js","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.js"},"./internal":{"types":"./dist/internal.d.ts","import":"./dist/internal.js","require":"./dist/internal.js"},"./secrets-vault":{"types":"./dist/secrets-vault.d.ts","import":"./dist/secrets-vault.js","require":"./dist/secrets-vault.js"}},"gitHead":"127bce5247c707bf7eba4375b856dedc3036818d","scripts":{"test":"jest","build":"tsc -p tsconfig.build.json","prepare":"tsc -p tsconfig.build.json","test:int":"jest tests/integration","test:unit":"jest tests/unit","secrets-vault":"node scripts/secrets_vault_cli.mjs","version:validate":"node scripts/version_manager.mjs validate","version:bump:patch":"node scripts/version_manager.mjs bump patch"},"_npmUser":{"name":"the_axol0tl","email":"mng@dexalot.com"},"_npmVersion":"11.3.0","description":"Here is our first public release of Dexalot SDK for TypeScript.  It is in alpha testing right now.  Fork it, contribute to it and use it to integrate with Dexalot and let us know how we can improve it.","directories":{},"_nodeVersion":"22.11.0","dependencies":{"axios":"1.14.0","dotenv":"16.6.1","ethers":"6.16.0","typescript":"5.9.3"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"packageManager":"pnpm@10.13.1+sha512.37ebf1a5c7a30d5fabe0c5df44ee8da4c965ca0c5af3dbab28c3a1681b70a256218d05c81c9c0dcf767ef6b8551eb5b960042b9ed4300c59242336377e01cfad","devDependencies":{"jest":"29.7.0","ts-jest":"29.4.9","@types/jest":"29.5.14","@types/node":"22.19.15"},"_npmOperationalInternal":{"tmp":"tmp/dexalot-sdk_0.5.16_1775499014040_0.8135866236494169","host":"s3://npm-registry-packages-npm-production"}},"0.5.17":{"name":"@dexalot/dexalot-sdk","version":"0.5.17","license":"MIT","_id":"@dexalot/dexalot-sdk@0.5.17","maintainers":[{"name":"ilkerdexalot","email":"ilker@dexalot.com"},{"name":"the_axol0tl","email":"mng@dexalot.com"}],"homepage":"https://github.com/Dexalot/dexalot-sdk-typescript#readme","bugs":{"url":"https://github.com/Dexalot/dexalot-sdk-typescript/issues"},"dist":{"shasum":"82d4b2e81ccb69e92a11e77813c00aa3182e8830","tarball":"https://registry.npmjs.org/@dexalot/dexalot-sdk/-/dexalot-sdk-0.5.17.tgz","fileCount":193,"integrity":"sha512-v6BtZSy+8gOx2ozldYh5VElSlvNZXLOAe1t79OkcoQygomhgjxlhTwJ0Ft6eoXZz1FsgWzOJjxsCjflPtI6dSQ==","signatures":[{"sig":"MEQCIDVnTXPdA7P+QLRpAB0Sw5rwZ7pZ7l/hGq0uyGevEGk/AiB7QfUkeQOuh8aFe6SVXsWb8KxIgXHxcyysazeaGbe0lg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@dexalot%2fdexalot-sdk@0.5.17","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":1908632},"main":"dist/index.js","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.js"},"./internal":{"types":"./dist/internal.d.ts","import":"./dist/internal.js","require":"./dist/internal.js"},"./secrets-vault":{"types":"./dist/secrets-vault.d.ts","import":"./dist/secrets-vault.js","require":"./dist/secrets-vault.js"}},"gitHead":"38ca875fbda68e8be2d365507111f38dcc0030fe","scripts":{"test":"jest","build":"tsc -p tsconfig.build.json","prepare":"tsc -p tsconfig.build.json","test:int":"jest tests/integration","test:unit":"jest tests/unit","secrets-vault":"node scripts/secrets_vault_cli.mjs","version:validate":"node scripts/version_manager.mjs validate","version:bump:patch":"node scripts/version_manager.mjs bump patch"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:1385059e-0f6e-42c3-ab59-114a4b7abd37"}},"repository":{"url":"git+https://github.com/Dexalot/dexalot-sdk-typescript.git","type":"git"},"_npmVersion":"11.12.1","description":"Here is our first public release of Dexalot SDK for TypeScript.  It is in alpha testing right now.  Fork it, contribute to it and use it to integrate with Dexalot and let us know how we can improve it.","directories":{},"_nodeVersion":"22.22.2","dependencies":{"axios":"1.14.0","dotenv":"16.6.1","ethers":"6.16.0","typescript":"5.9.3"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"packageManager":"pnpm@10.13.1+sha512.37ebf1a5c7a30d5fabe0c5df44ee8da4c965ca0c5af3dbab28c3a1681b70a256218d05c81c9c0dcf767ef6b8551eb5b960042b9ed4300c59242336377e01cfad","devDependencies":{"jest":"29.7.0","ts-jest":"29.4.9","@types/jest":"29.5.14","@types/node":"22.19.15"},"_npmOperationalInternal":{"tmp":"tmp/dexalot-sdk_0.5.17_1775582826302_0.9926757841741503","host":"s3://npm-registry-packages-npm-production"}},"0.5.18":{"name":"@dexalot/dexalot-sdk","version":"0.5.18","license":"MIT","_id":"@dexalot/dexalot-sdk@0.5.18","maintainers":[{"name":"ilkerdexalot","email":"ilker@dexalot.com"},{"name":"the_axol0tl","email":"mng@dexalot.com"}],"homepage":"https://github.com/Dexalot/dexalot-sdk-typescript#readme","bugs":{"url":"https://github.com/Dexalot/dexalot-sdk-typescript/issues"},"dist":{"shasum":"5eabe1985a8a985b4d2c150e1cd63082b0e6aaf5","tarball":"https://registry.npmjs.org/@dexalot/dexalot-sdk/-/dexalot-sdk-0.5.18.tgz","fileCount":230,"integrity":"sha512-skHJDULafI5Lb18pzdbDhfL3Hz6kh9FpuBA3vDRH3u1NhMX4auZKUffsF8xrVwlxQRaGqWm8HdDM4GIGDaMF1A==","signatures":[{"sig":"MEUCIQC0KRSPflREt0kmOeqls8YL+Xj+hiBAkNCU8A2ypx02ZwIgB6mlWoEQkxnon5VPXeFIji04ibv2QHsYJnFFHCpGYCw=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@dexalot%2fdexalot-sdk@0.5.18","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":2357346},"main":"dist/index.js","pnpm":{"overrides":{"ws":"^8.18.0"}},"types":"dist/index.d.ts","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.js"},"./internal":{"types":"./dist/internal.d.ts","import":"./dist/internal.js","require":"./dist/internal.js"},"./secrets-vault":{"types":"./dist/secrets-vault.d.ts","import":"./dist/secrets-vault.js","require":"./dist/secrets-vault.js"}},"gitHead":"c0866883b77ceca86c90f6da33238edc426c9f28","scripts":{"cov":"jest tests/unit --coverage","test":"jest","build":"tsc -p tsconfig.build.json","example":"tsx","prepare":"tsc -p tsconfig.build.json","test:int":"jest tests/integration","test:unit":"jest tests/unit","typecheck":"tsc --noEmit","audit:high":"pnpm audit --audit-level=high","secrets-vault":"node scripts/secrets_vault_cli.mjs","version:validate":"node scripts/version_manager.mjs validate","typecheck:examples":"tsc --noEmit -p tsconfig.examples.json","version:bump:patch":"node scripts/version_manager.mjs bump patch"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:1385059e-0f6e-42c3-ab59-114a4b7abd37"}},"overrides":{"ws":"^8.18.0"},"repository":{"url":"git+https://github.com/Dexalot/dexalot-sdk-typescript.git","type":"git"},"_npmVersion":"11.12.1","description":"Here is our first public release of Dexalot SDK for TypeScript.  It is in alpha testing right now.  Fork it, contribute to it and use it to integrate with Dexalot and let us know how we can improve it.","directories":{},"_nodeVersion":"22.22.3","dependencies":{"axios":"1.16.1","big.js":"7.0.1","dotenv":"16.6.1","ethers":"6.16.0","typescript":"5.9.3"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"packageManager":"pnpm@10.13.1+sha512.37ebf1a5c7a30d5fabe0c5df44ee8da4c965ca0c5af3dbab28c3a1681b70a256218d05c81c9c0dcf767ef6b8551eb5b960042b9ed4300c59242336377e01cfad","devDependencies":{"tsx":"^4.22.3","jest":"29.7.0","ts-jest":"29.4.9","@types/jest":"29.5.14","@types/node":"22.19.15","@types/big.js":"7.0.0"},"_npmOperationalInternal":{"tmp":"tmp/dexalot-sdk_0.5.18_1779895382730_0.4073892392359786","host":"s3://npm-registry-packages-npm-production"}},"0.5.19":{"name":"@dexalot/dexalot-sdk","version":"0.5.19","license":"MIT","_id":"@dexalot/dexalot-sdk@0.5.19","maintainers":[{"name":"ilkerdexalot","email":"ilker@dexalot.com"},{"name":"the_axol0tl","email":"mng@dexalot.com"}],"homepage":"https://github.com/Dexalot/dexalot-sdk-typescript#readme","bugs":{"url":"https://github.com/Dexalot/dexalot-sdk-typescript/issues"},"dist":{"shasum":"4d7c6256e297dca924e6aa7438076625d9d7f82f","tarball":"https://registry.npmjs.org/@dexalot/dexalot-sdk/-/dexalot-sdk-0.5.19.tgz","fileCount":231,"integrity":"sha512-OYPEejyaSxBO5okaippdiaXeQG4AIfZqxYWQ/u1oFuXFJF5LNz4uwlZAtio30ww8Wb0Qj6zD7UXjRsFq9HRKvA==","signatures":[{"sig":"MEUCIQDYPARX66DBOInUg6GyTsMYJ4EcHuGKoGeobqnOMmGeBwIgEa9AsgkPGs0bzgnsdkbcYKUgVPvfjW/HM38UeWMMDcM=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@dexalot%2fdexalot-sdk@0.5.19","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":2543167},"main":"dist/index.js","pnpm":{"overrides":{"ws":"^8.18.0","esbuild":"^0.28.1","form-data":"^4.0.6","@babel/core":"^7.29.6"}},"types":"dist/index.d.ts","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.js"},"./internal":{"types":"./dist/internal.d.ts","import":"./dist/internal.js","require":"./dist/internal.js"},"./secrets-vault":{"types":"./dist/secrets-vault.d.ts","import":"./dist/secrets-vault.js","require":"./dist/secrets-vault.js"}},"gitHead":"8508d8dcfe24c7fe1d164259fb0fa19462027ce1","scripts":{"cov":"jest tests/unit --coverage","test":"jest","build":"tsc -p tsconfig.build.json","example":"tsx","prepare":"tsc -p tsconfig.build.json","test:int":"jest tests/integration","test:unit":"jest tests/unit","typecheck":"tsc --noEmit","audit:high":"pnpm audit --audit-level=high","secrets-vault":"node scripts/secrets_vault_cli.mjs","version:validate":"node scripts/version_manager.mjs validate","typecheck:examples":"tsc --noEmit -p tsconfig.examples.json","version:bump:patch":"node scripts/version_manager.mjs bump patch"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:1385059e-0f6e-42c3-ab59-114a4b7abd37"}},"overrides":{"ws":"^8.18.0","esbuild":"^0.28.1","form-data":"^4.0.6","@babel/core":"^7.29.6"},"repository":{"url":"git+https://github.com/Dexalot/dexalot-sdk-typescript.git","type":"git"},"_npmVersion":"11.12.1","description":"Here is our first public release of Dexalot SDK for TypeScript.  It is in alpha testing right now.  Fork it, contribute to it and use it to integrate with Dexalot and let us know how we can improve it.","directories":{},"_nodeVersion":"22.22.3","dependencies":{"axios":"1.16.1","big.js":"7.0.1","dotenv":"16.6.1","ethers":"6.16.0","typescript":"5.9.3"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"packageManager":"pnpm@10.13.1+sha512.37ebf1a5c7a30d5fabe0c5df44ee8da4c965ca0c5af3dbab28c3a1681b70a256218d05c81c9c0dcf767ef6b8551eb5b960042b9ed4300c59242336377e01cfad","devDependencies":{"tsx":"^4.22.3","jest":"29.7.0","ts-jest":"29.4.9","@types/jest":"29.5.14","@types/node":"22.19.15","@types/big.js":"7.0.0"},"_npmOperationalInternal":{"tmp":"tmp/dexalot-sdk_0.5.19_1781607253202_0.6927769981331775","host":"s3://npm-registry-packages-npm-production"}},"0.6.0":{"name":"@dexalot/dexalot-sdk","version":"0.6.0","license":"MIT","_id":"@dexalot/dexalot-sdk@0.6.0","maintainers":[{"name":"ilkerdexalot","email":"ilker@dexalot.com"},{"name":"the_axol0tl","email":"mng@dexalot.com"}],"homepage":"https://github.com/Dexalot/dexalot-sdk-typescript#readme","bugs":{"url":"https://github.com/Dexalot/dexalot-sdk-typescript/issues"},"dist":{"shasum":"85cb1087e08a557e56ad7baf355c872394d91680","tarball":"https://registry.npmjs.org/@dexalot/dexalot-sdk/-/dexalot-sdk-0.6.0.tgz","fileCount":237,"integrity":"sha512-i5RIJmeM9AHaNsOyFbTe1xhMabKuw6jICts1NIDnB505n1+C5Rb5oOM5gN8su1WHMGqrdYH1KPf/YcQekng8fA==","signatures":[{"sig":"MEYCIQCwFfcGORrPMelXfnkICT65f1TAUIZ1Cj1MLUfwn+DvQQIhAL2SqRKU28oV91YCLuFbRt7JWNke0bqfSwaGSSbP/DAu","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@dexalot%2fdexalot-sdk@0.6.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":2596033},"main":"dist/index.js","pnpm":{"overrides":{"ws":"^8.18.0","esbuild":"^0.28.1","form-data":"^4.0.6","@babel/core":"^7.29.6"}},"types":"dist/index.d.ts","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.js"},"./internal":{"types":"./dist/internal.d.ts","import":"./dist/internal.js","require":"./dist/internal.js"},"./secrets-vault":{"types":"./dist/secrets-vault.d.ts","import":"./dist/secrets-vault.js","require":"./dist/secrets-vault.js"}},"gitHead":"a1e387a21a36982dbef87c9bd42bab8ec5e8b3be","scripts":{"cov":"jest tests/unit --coverage","test":"jest","build":"tsc -p tsconfig.build.json","example":"tsx","prepare":"tsc -p tsconfig.build.json","test:int":"jest tests/integration","test:unit":"jest tests/unit","typecheck":"tsc --noEmit","audit:high":"pnpm audit --audit-level=high","secrets-vault":"node scripts/secrets_vault_cli.mjs","version:validate":"node scripts/version_manager.mjs validate","typecheck:examples":"tsc --noEmit -p tsconfig.examples.json","version:bump:patch":"node scripts/version_manager.mjs bump patch"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:1385059e-0f6e-42c3-ab59-114a4b7abd37"}},"overrides":{"ws":"^8.18.0","esbuild":"^0.28.1","form-data":"^4.0.6","@babel/core":"^7.29.6"},"repository":{"url":"git+https://github.com/Dexalot/dexalot-sdk-typescript.git","type":"git"},"_npmVersion":"11.12.1","description":"Here is our first public release of Dexalot SDK for TypeScript.  It is in alpha testing right now.  Fork it, contribute to it and use it to integrate with Dexalot and let us know how we can improve it.","directories":{},"_nodeVersion":"22.22.3","dependencies":{"axios":"1.16.1","big.js":"7.0.1","dotenv":"16.6.1","ethers":"6.16.0","typescript":"5.9.3"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"packageManager":"pnpm@10.13.1+sha512.37ebf1a5c7a30d5fabe0c5df44ee8da4c965ca0c5af3dbab28c3a1681b70a256218d05c81c9c0dcf767ef6b8551eb5b960042b9ed4300c59242336377e01cfad","devDependencies":{"tsx":"^4.22.3","jest":"29.7.0","ts-jest":"29.4.9","@types/jest":"29.5.14","@types/node":"22.19.15","@types/big.js":"7.0.0"},"_npmOperationalInternal":{"tmp":"tmp/dexalot-sdk_0.6.0_1781718600054_0.09939463569292539","host":"s3://npm-registry-packages-npm-production"}},"0.6.1":{"name":"@dexalot/dexalot-sdk","version":"0.6.1","license":"MIT","_id":"@dexalot/dexalot-sdk@0.6.1","maintainers":[{"name":"ilkerdexalot","email":"ilker@dexalot.com"},{"name":"the_axol0tl","email":"mng@dexalot.com"}],"homepage":"https://github.com/Dexalot/dexalot-sdk-typescript#readme","bugs":{"url":"https://github.com/Dexalot/dexalot-sdk-typescript/issues"},"dist":{"shasum":"f0467cf61821cf7ee2433bb2cb8d5dfa55042463","tarball":"https://registry.npmjs.org/@dexalot/dexalot-sdk/-/dexalot-sdk-0.6.1.tgz","fileCount":237,"integrity":"sha512-EC133bTvrzbyeiaf64Sog4XbARhcczQjixMk2Lec30Z4FWM0vA0/ix3QZfVGrkeVpvasKEoxnufmSF4ugXYr+A==","signatures":[{"sig":"MEUCIQCwciUBv4Nn+n5O46YFot4qqBqFuJjCwF+loHtLziHN3QIgY1eZf5YDhENPYyuRfMau0rxHJYzJLzDmcqzrpdH3Sek=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEQCIFTErhOLsYQgSRgQ/YlNIi+gjU0bdOoq1qLzP6jpHwH4AiBF34M0N4zbpxLn74lpCwLdcJCMXQoFhQutq3uuLzKblQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@dexalot%2fdexalot-sdk@0.6.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":2681408},"main":"dist/index.js","pnpm":{"overrides":{"ws":"^8.18.0","esbuild":"^0.28.1","form-data":"^4.0.6","js-yaml@3":">=3.15.2","@babel/core":"^7.29.6","browserslist":">=4.29.0","brace-expansion@1":">=1.1.21"}},"types":"dist/index.d.ts","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.js"},"./internal":{"types":"./dist/internal.d.ts","import":"./dist/internal.js","require":"./dist/internal.js"},"./secrets-vault":{"types":"./dist/secrets-vault.d.ts","import":"./dist/secrets-vault.js","require":"./dist/secrets-vault.js"}},"gitHead":"0d756a92a61b88e24ea69482cc796cd4e86a39b8","scripts":{"cov":"jest tests/unit --coverage","test":"jest","build":"tsc -p tsconfig.build.json","example":"tsx","prepare":"tsc -p tsconfig.build.json","test:int":"jest tests/integration","test:unit":"jest tests/unit","typecheck":"tsc --noEmit","audit:high":"pnpm audit --audit-level=high","secrets-vault":"node scripts/secrets_vault_cli.mjs","version:validate":"node scripts/version_manager.mjs validate","typecheck:examples":"tsc --noEmit -p tsconfig.examples.json","version:bump:patch":"node scripts/version_manager.mjs bump patch"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:1385059e-0f6e-42c3-ab59-114a4b7abd37"}},"overrides":{"ws":"^8.18.0","esbuild":"^0.28.1","js-yaml":">=3.15.2","form-data":"^4.0.6","@babel/core":"^7.29.6","browserslist":">=4.29.0","brace-expansion":">=1.1.21"},"repository":{"url":"git+https://github.com/Dexalot/dexalot-sdk-typescript.git","type":"git"},"_npmVersion":"11.12.1","description":"Here is our first public release of Dexalot SDK for TypeScript.  It is in alpha testing right now.  Fork it, contribute to it and use it to integrate with Dexalot and let us know how we can improve it.","directories":{},"_nodeVersion":"22.23.2","dependencies":{"axios":"1.20.0","big.js":"7.0.1","dotenv":"16.6.1","ethers":"6.16.0","typescript":"5.9.3"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"packageManager":"pnpm@10.13.1+sha512.37ebf1a5c7a30d5fabe0c5df44ee8da4c965ca0c5af3dbab28c3a1681b70a256218d05c81c9c0dcf767ef6b8551eb5b960042b9ed4300c59242336377e01cfad","devDependencies":{"tsx":"^4.22.3","jest":"29.7.0","ts-jest":"29.4.9","@types/jest":"29.5.14","@types/node":"22.19.15","@types/big.js":"7.0.0"},"_npmOperationalInternal":{"tmp":"tmp/dexalot-sdk_0.6.1_1789813541911_0.3236553676341587","host":"s3://npm-registry-packages-npm-production"}},"0.6.2":{"_id":"@dexalot/dexalot-sdk@0.6.2","bugs":{"url":"https://github.com/Dexalot/dexalot-sdk-typescript/issues"},"dist":{"shasum":"d1ed2bfa4eef9ede487b00e43bf6834ad35c81fe","tarball":"https://registry.npmjs.org/@dexalot/dexalot-sdk/-/dexalot-sdk-0.6.2.tgz","fileCount":237,"integrity":"sha512-FzKIQzBiTeT9uIU62D4bZNAh/448HriJJg802KxXzrHgYTeRM3kgWalJjTuRmliyRYph3WckB6pAkJgv2Z3k5w==","signatures":[{"sig":"MEYCIQDsb+mzugX5LUM8KxZHCY+n+yUocWQ69yhISrG+ZXSXMgIhAOwsB7igtnrF403+kIAkFO14cirgP472QSn8U4iy87Ai","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIDurJB/RLx/CJAXI9Ix8NOqDkCPynDlJMges/itqekW1AiEAtedchMvMncfAV3XwZQzN1YmBr+OmZetWKfnroD/AjsQ="}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@dexalot%2fdexalot-sdk@0.6.2","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":2708538},"main":"dist/index.js","name":"@dexalot/dexalot-sdk","pnpm":{"overrides":{"ws":"^8.18.0","esbuild":"^0.28.1","form-data":"^4.0.6","js-yaml@3":">=3.15.2","@babel/core":"^7.29.6","browserslist":">=4.29.0","brace-expansion@1":">=1.1.21"}},"types":"dist/index.d.ts","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.js"},"./internal":{"types":"./dist/internal.d.ts","import":"./dist/internal.js","require":"./dist/internal.js"},"./secrets-vault":{"types":"./dist/secrets-vault.d.ts","import":"./dist/secrets-vault.js","require":"./dist/secrets-vault.js"}},"gitHead":"211d639c9a86ccd87dcd92fcbda4420ab993929e","license":"MIT","scripts":{"cov":"jest tests/unit --coverage","test":"jest","build":"tsc -p tsconfig.build.json","example":"tsx","prepare":"tsc -p tsconfig.build.json","test:int":"jest tests/integration","test:unit":"jest tests/unit","typecheck":"tsc --noEmit","audit:high":"pnpm audit --audit-level=high","secrets-vault":"node scripts/secrets_vault_cli.mjs","version:validate":"node scripts/version_manager.mjs validate","typecheck:examples":"tsc --noEmit -p tsconfig.examples.json","version:bump:patch":"node scripts/version_manager.mjs bump patch"},"version":"0.6.2","_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:1385059e-0f6e-42c3-ab59-114a4b7abd37"}},"homepage":"https://github.com/Dexalot/dexalot-sdk-typescript#readme","overrides":{"ws":"^8.18.0","esbuild":"^0.28.1","js-yaml":">=3.15.2","form-data":"^4.0.6","@babel/core":"^7.29.6","browserslist":">=4.29.0","brace-expansion":">=1.1.21"},"repository":{"url":"git+https://github.com/Dexalot/dexalot-sdk-typescript.git","type":"git"},"_npmVersion":"11.12.1","description":"Here is our first public release of Dexalot SDK for TypeScript.  It is in alpha testing right now.  Fork it, contribute to it and use it to integrate with Dexalot and let us know how we can improve it.","directories":{},"maintainers":[{"name":"ilkerdexalot","email":"ilker@dexalot.com"},{"name":"the_axol0tl","email":"mng@dexalot.com"}],"_nodeVersion":"22.23.2","dependencies":{"axios":"1.20.0","big.js":"7.0.1","dotenv":"16.6.1","ethers":"6.16.0","typescript":"5.9.3"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"packageManager":"pnpm@10.13.1+sha512.37ebf1a5c7a30d5fabe0c5df44ee8da4c965ca0c5af3dbab28c3a1681b70a256218d05c81c9c0dcf767ef6b8551eb5b960042b9ed4300c59242336377e01cfad","devDependencies":{"tsx":"^4.22.3","jest":"29.7.0","ts-jest":"29.4.9","@types/jest":"29.5.14","@types/node":"22.19.15","@types/big.js":"7.0.0"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/dexalot-sdk_0.6.2_1789896939849_0.06274199917182588"}}},"time":{"created":"2026-04-06T17:59:22.209Z","modified":"2026-09-20T09:35:40.276Z","0.5.15":"2026-04-06T17:59:22.440Z","0.5.16":"2026-04-06T18:10:14.248Z","0.5.17":"2026-04-07T17:27:06.607Z","0.5.18":"2026-05-27T15:23:02.936Z","0.5.19":"2026-06-16T10:54:13.415Z","0.6.0":"2026-06-17T17:50:00.287Z","0.6.1":"2026-09-19T10:25:42.031Z","0.6.2":"2026-09-20T09:35:39.940Z"},"bugs":{"url":"https://github.com/Dexalot/dexalot-sdk-typescript/issues"},"license":"MIT","homepage":"https://github.com/Dexalot/dexalot-sdk-typescript#readme","repository":{"url":"git+https://github.com/Dexalot/dexalot-sdk-typescript.git","type":"git"},"description":"Here is our first public release of Dexalot SDK for TypeScript.  It is in alpha testing right now.  Fork it, contribute to it and use it to integrate with Dexalot and let us know how we can improve it.","maintainers":[{"name":"ilkerdexalot","email":"ilker@dexalot.com"},{"name":"the_axol0tl","email":"mng@dexalot.com"}],"readme":"# Dexalot TypeScript SDK\n\n## Disclaimer\n\nHere is our first public release of Dexalot SDK for TypeScript.  It is in alpha testing right now.  Fork it, contribute to it and use it to integrate with Dexalot and let us know how we can improve it.\n\n**Pleaase Note**: The public interface may undergo breaking changes.\n\n## Overview\n\n`dexalot-sdk` is a TypeScript/JavaScript library that provides core functionality for interacting with the Dexalot decentralized exchange. It offers a unified client interface for trading operations, cross-chain transfers, and portfolio management across multiple blockchain networks.\n\n## Features\n\n- **Unified Client**: Single `DexalotClient` interface for all Dexalot operations\n- **Modular Architecture**: Functional mixins for CLOB, Swap, and Transfer operations\n- **Multi-Chain Support**: Works with Dexalot L1 subnet and connected mainnet networks\n- **Type Safety**: Full TypeScript support with comprehensive type definitions\n- **Caching**: TTL-based memory cache utilities for performance optimization\n\n## Architecture\n\n### Core Components\n\n- **`core/client.ts`**: Unified `DexalotClient` composed from modular mixins\n- **`core/base.ts`**: Environment setup, Web3 connections, error handling\n- **`core/clob.ts`**: Central Limit Order Book trading operations\n- **`core/swap.ts`**: SimpleSwap RFQ (Request for Quote) functionality\n- **`core/transfer.ts`**: Cross-chain deposits/withdrawals, portfolio management\n\n### Utilities\n\n- **`utils/input_validators.ts`**: Validate SDK method input parameters (amounts, addresses, pairs, etc.)\n- **`utils/cache.ts`**: TTL-based caching utilities (`MemoryCache`, `withCache`, `withInstanceCache`)\n- **`utils/observability.ts`**: Structured logging and operation tracking\n- **`utils/result.ts`**: Standardized `Result<T>` type for consistent error handling\n- **`utils/retry.ts`**: Async retry decorator with exponential backoff\n- **`utils/rateLimit.ts`**: Token bucket rate limiter for API and RPC calls\n- **`utils/nonceManager.ts`**: Thread-safe nonce management to prevent transaction race conditions\n- **`utils/providerManager.ts`**: RPC provider failover with health tracking\n- **`utils/errorSanitizer.ts`**: Error message sanitization to prevent information leakage\n- **`utils/websocketManager.ts`**: Persistent WebSocket connection manager with reconnection and heartbeat\n\n## Installation\n\nInstall the SDK using pnpm (recommended):\n\n```sh\npnpm add @dexalot/dexalot-sdk\n```\n\nOr use alternative package managers:\n\n```sh\n# npm\nnpm install @dexalot/dexalot-sdk\n\n# yarn\nyarn add @dexalot/dexalot-sdk\n```\n\nOr install directly from the repository (the `prepare` script builds\n`dist/` automatically, so no separate build step is needed):\n\n```sh\npnpm add github:Dexalot/dexalot-sdk-typescript\n```\n\n## Package exports\n\n- **`dexalot-sdk`**: Default export `DexalotClient`, plus `DexalotConfig` (type), `createConfig`, `loadConfigFromEnv`, `MemoryCache`, `Result`, `getLogger` / `Logger`, `version`, and `getVersion()`.\n- **`dexalot-sdk/secrets-vault`**: `generateSecretsVaultKey`, `secretsVaultGet` / `Set` / `List` / `Remove`.\n- **`dexalot-sdk/internal`**: `BaseClient`, `CLOBClient`, `SwapClient`, `TransferClient`, `Utils`, types, constants, and the rest of the implementation surface for advanced use (excludes the secrets vault; use the subpath above).\n\nCall `await client.initializeClient()` before trading RPC/API usage, optionally `await client.connect()`, and `await client.close()` when tearing down. Successful on-chain `Result` payloads use camelCase fields such as `txHash`, `operation`, and batch id lists where applicable.\n\n## Secrets Vault\n\nThe Node-only secrets vault is exported from `dexalot-sdk/secrets-vault`. It stores encrypted values in a local Fernet-encrypted JSON file using the shared Dexalot vault format, so Python and TypeScript tooling can read the same vault file.\n\nDefault path:\n\n```sh\n~/.dexalot/secrets_vault.json\n```\n\nEnvironment variables:\n\n```sh\nDEXALOT_SECRETS_VAULT_KEY=<your-fernet-key>\nDEXALOT_SECRETS_VAULT_PATH=~/.dexalot/secrets_vault.json\n```\n\nExample:\n\n```typescript\nimport {\n    generateSecretsVaultKey,\n    secretsVaultSet,\n    secretsVaultGet,\n} from \"dexalot-sdk/secrets-vault\";\n\nconst key = generateSecretsVaultKey();\nsecretsVaultSet(\"~/.dexalot/secrets_vault.json\", \"PRIVATE_KEY\", \"0x...\", key);\nconst result = secretsVaultGet(\"~/.dexalot/secrets_vault.json\", \"PRIVATE_KEY\", key);\n```\n\nA CLI helper is also available:\n\n```sh\nnpm run secrets-vault -- keygen\nnpm run secrets-vault -- add PRIVATE_KEY 0xabc123...\n```\n\n## Quick Start\n\n```typescript\nimport DexalotClient from 'dexalot-sdk';\n\nasync function main() {\n    let client: DexalotClient | null = null;\n    try {\n        // Initialize client\n        client = new DexalotClient();\n        const result = await client.initializeClient();\n        \n        if (!result.success) {\n            console.error(`Initialization failed: ${result.error}`);\n            return;\n        }\n        \n        // Fetch trading pairs (stores pairs in client.pairs)\n        const pairsResult = await client.getClobPairs();\n        if (pairsResult.success) {\n            console.log(`Available pairs: ${Object.keys(client.pairs)}`);\n        } else {\n            console.error(`Error: ${pairsResult.error}`);\n        }\n    } finally {\n        // Always close the client to clean up resources\n        if (client !== null) {\n            await client.close();\n        }\n    }\n}\n\n// Run the async function\nmain().catch(console.error);\n```\n\n**Key Points:**\n- The SDK is **fully async** - all methods must be awaited\n- All methods return `Result<T>` for consistent error handling\n- Use `async/await` for async contexts\n- Always call `await client.close()` when done to clean up resources\n\n## Usage\n\n### Basic Async Usage\n\n```typescript\nimport DexalotClient from 'dexalot-sdk';\n\nasync function main() {\n    let client: DexalotClient | null = null;\n    try {\n        client = new DexalotClient();\n        \n        // Initialize client (required before other operations)\n        const initResult = await client.initializeClient();\n        if (!initResult.success) {\n            console.error(`Failed to initialize: ${initResult.error}`);\n            return;\n        }\n        \n        // Get available trading pairs (stores pairs in client.pairs)\n        const pairsResult = await client.getClobPairs();\n        if (pairsResult.success) {\n            console.log(`Found ${Object.keys(client.pairs).length} trading pairs`);\n        } else {\n            console.error(`Error fetching pairs: ${pairsResult.error}`);\n        }\n    } finally {\n        // Always close the client to clean up resources\n        if (client !== null) {\n            await client.close();\n        }\n    }\n}\n\nmain().catch(console.error);\n```\n\n### Error Handling with Result Pattern\n\nAll SDK methods return `Result<T>` which provides consistent error handling:\n\n```typescript\nconst result = await client.getOrderBook(\"AVAX/USDC\");\n\nif (result.success) {\n    const orderbook = result.data;\n    console.log(`Bids: ${orderbook.bids}`);\n    console.log(`Asks: ${orderbook.asks}`);\n} else {\n    console.error(`Error: ${result.error}`);\n    // Handle error appropriately\n}\n```\n\n### Order history\n\n```typescript\nconst result = await client.getOrderHistory(undefined, {\n    pair: \"ALOT/USDC\",\n    status: \"FILLED\",\n    limit: 50,\n});\nif (result.success) {\n    for (const order of result.data) {\n        console.log(`${order.pair} ${order.side} ${order.quantity} @ ${order.price}`);\n    }\n}\n```\n\n### Order Types & Time-in-Force\n\nCLOB orders are described by three on-chain fields, all optional on `OrderRequest`\nand defaulting to today's behavior:\n\n- **`type`** (`type1`) — `'LIMIT'` (default) or `'MARKET'`.\n- **`timeInForce`** (`type2`) — `'GTC'` (default), `'FOK'`, `'IOC'`, or `'PO'`\n  (Post-Only). Aliases like `'POST_ONLY'` / `'FILL_OR_KILL'` are accepted.\n- **`stp`** (self-trade prevention) — `'CANCEL_TAKER'` (default),\n  `'CANCEL_MAKER'`, `'CANCEL_BOTH'`, or `'CANCEL_NONE'` (contract spellings\n  `'CANCELTAKER'` etc. also accepted).\n\n> Stop / stop-limit orders cannot be **placed**: although the contract `Type1`\n> enum reserves `STOP`/`STOPLIMIT`, they are unused on-chain, so `type` accepts\n> only `MARKET`/`LIMIT`. Order *reads* still label `type1` 2/3 as\n> `STOP`/`STOPLIMIT` for fidelity with the contract enum.\n\nThe SDK only pre-validates the rule the contract relies on — a `LIMIT` order\nrequires a price — and defers the rest to on-chain reverts (`MARKET` ignores\n`timeInForce`/price; Post-Only, per-pair allowed types, FOK and self-trade are\nenforced on-chain: `T-IVOT-01`, `T-POOA-01`, `T-T2PO-01`, `T-FOKF-01`,\n`T-STPR-01`).\n\n```typescript\n// Limit IOC\nawait client.addOrder({ pair: 'AVAX/USDC', side: 'BUY', amount: 1, price: 25, timeInForce: 'IOC' });\n\n// Post-Only (maker-only)\nawait client.addOrder({ pair: 'AVAX/USDC', side: 'SELL', amount: 1, price: 25, timeInForce: 'PO' });\n\n// Market BUY (no price)\nawait client.addOrder({ pair: 'AVAX/USDC', side: 'BUY', amount: 1, type: 'MARKET' });\n\n// Self-trade prevention\nawait client.addOrder({ pair: 'AVAX/USDC', side: 'BUY', amount: 1, price: 25, stp: 'CANCEL_MAKER' });\n\n// Batch with mixed types (addOrderList is an alias for addLimitOrderList)\nawait client.addOrderList([\n    { pair: 'AVAX/USDC', side: 'BUY', amount: 1, price: 24, timeInForce: 'PO' },\n    { pair: 'AVAX/USDC', side: 'SELL', amount: 1, type: 'MARKET', timeInForce: 'IOC' },\n]);\n```\n\n`replaceOrder` uses the contract's `cancelReplaceOrder`, which carries only a\nnew price and quantity — the replacement **inherits** the original order's\n`type1`/`timeInForce`/`stp`. To change those, cancel and place a new order\n(e.g. via `cancelAddList`).\n\n## Dependencies\n\n- `ethers>=6.0.0`: Multi-chain blockchain interactions\n- `axios`: HTTP client for Dexalot API communication\n- `dotenv`: Environment variable management\n\n## Testing\n\nRun tests from the package directory:\n\n```sh\npnpm test          # Unit tests\npnpm test:unit     # Unit tests only\npnpm test:int      # Integration tests\n```\n\n## Release\n\nReleases are **tag-driven**. Pushing a `v*` tag to `main` triggers\n`.github/workflows/npm.yml`, which builds the package and publishes\nto NPM via trusted publishing (OIDC — no long-lived NPM token is\nstored anywhere) with `npm publish --provenance` for supply-chain\nattestation.\n\n**Release gates (all enforced by the workflow):**\n\n1. `github.ref_type` must be `tag` (not `branch`).\n2. The tagged commit must be reachable from `origin/main`\n   (`git merge-base --is-ancestor`). Tags on throwaway branches will\n   not publish.\n3. The tag name must equal `v{package.json version}`.\n\n**Steps:**\n\n1. Sync the version across all version-bearing files:\n\n   ```sh\n   pnpm run version:bump:patch\n   # touches package.json, VERSION, src/version.ts\n   ```\n\n2. Review the diff, commit on a feature branch, and merge a PR into\n   `main`.\n\n3. From `main`, tag and push:\n\n   ```sh\n   git checkout main && git pull\n   git tag -a v<new-version> -m \"Release v<new-version>\"\n   git push origin v<new-version>\n   ```\n\n4. Watch the **Publish to NPM** workflow in GitHub Actions. On green,\n   verify the new version at\n   <https://npmjs.com/package/@dexalot/dexalot-sdk>.\n\n> ⚠️ Once a version is published to NPM it cannot be re-uploaded\n> under the same number; `npm deprecate` is the available\n> remediation. Always bump the version before tagging.\n>\n> Version numbers `v0.5.18` and `v0.5.19` previously existed as\n> local-only orphan tags and were never published. Reusing them\n> would confuse operators — the next release after `v0.5.17` should\n> start at `v0.5.20` or later.\n\n## Caching\n\nThe SDK includes a built-in 4-level caching system to optimize performance by reducing redundant API calls. Caching is **enabled by default** with sensible TTL (Time-To-Live) values.\n\n> **📖 Detailed Documentation**: See [SDK Caching Guide](../../docs/sdk-caching.md) for comprehensive caching documentation, including advanced usage patterns, use cases, troubleshooting, and performance considerations.\n\n### Cache Levels\n\n| Level | Data Type | Default TTL | Examples |\n|-------|-----------|-------------|----------|\n| **Static** | Rarely changes | 1 hour | Environments, deployments, mainnets |\n| **Semi-Static** | Changes occasionally | 15 minutes | Tokens, trading pairs |\n| **Balance** | User-specific, updates frequently | 10 seconds | Portfolio balances, wallet balances |\n| **Orderbook** | Real-time data | 1 second | Order book snapshots |\n\n### Basic Usage\n\n```typescript\nimport DexalotClient from 'dexalot-sdk';\n\n// Caching is enabled by default\nconst client = new DexalotClient();\nawait client.initializeClient();\n\n// First call fetches from API\nconst balances = await client.getAllPortfolioBalances();\nconsole.log(balances);\n// { ALOT: { available: 95.5, locked: 4.5, total: 100.0 }, AVAX: ... }\n\n// Second call within 10 seconds returns cached result\nconst cachedBalances = await client.getAllPortfolioBalances(); // Cached!\n```\n\n### Configuration\n\nCustomize cache behavior during client initialization:\n\n```typescript\nimport DexalotClient, { createConfig } from 'dexalot-sdk';\n\n// Disable caching entirely\nconst clientNoCache = new DexalotClient(createConfig({ cacheEnabled: false }));\n\n// Custom TTL values (in seconds)\nconst clientCustomCache = new DexalotClient(createConfig({\n    cacheEnabled: true,\n    cacheTtlStatic: 7200,      // 2 hours for static data\n    cacheTtlSemiStatic: 1800,  // 30 minutes for semi-static\n    cacheTtlBalance: 5,         // 5 seconds for balances\n    cacheTtlOrderbook: 0.5     // 500ms for orderbook\n}));\n```\n\n### Cache Invalidation\n\nManually clear cached data when needed:\n\n```typescript\n// Clear all cache levels\nclient.invalidateCache();\n\n// Clear specific cache level\nclient.invalidateCache('balance'); // Options: 'static', 'semi_static', 'balance', 'orderbook', 'all'\n```\n\n### Cached Methods\n\n**Static Data (1 hour):**\n- `getEnvironments()`\n- `getChains()`\n- `getDeployment()` (also caches per `{env, contractType, returnAbi}` filter combination)\n- `getTokenPriceHistory(token, opts)`\n- `getTokenHourlyPriceHistory(token, opts)`\n\n**Semi-Static Data (15 minutes):**\n- `getTokens()`\n- `getClobPairs()`\n- `getSwapPairs(chainId)`\n- `getTokenUsdPrices(env?)`\n\n**Balance Data (10 seconds):**\n- `getChainTokenBalances(chain, tokens, address?)`\n- `getOrderHistory(account?, opts?)`\n- `getCombinedTransfers(opts?)` — `opts`: `{ symbol?, fromTs?, toTs?, limit?, offset? }`\n\n  | Param | Type | Description |\n  |---|---|---|\n  | `symbol` | `string` | Token symbol filter; canonicalized via `normalizeToken` (casing + aliases collapse). |\n  | `fromTs` | `number` | Inclusive window start, unix **seconds**. Sent to the backend as `periodfrom`. |\n  | `toTs` | `number` | Inclusive window end, unix **seconds**. Sent to the backend as `periodto`. |\n  | `limit` | `number` | Page size (default `100`). Translates to `itemsperpage = max(1, limit)`. |\n  | `offset` | `number` | Rows to skip (default `0`). Translates to `pageno = floor(offset / itemsperpage) + 1`. |\n\n  `limit`/`offset` translate to the backend's `itemsperpage`/`pageno` paging and `fromTs`/`toTs` to `periodfrom`/`periodto` internally; the cache key is built from the translated values, so equivalent `limit`/`offset` combos that land on the same page share a cache slot.\n\n**Orderbook Data (1 second):**\n- `getOrderBook(pair)`\n\n**Note:** Write operations (e.g., `addOrder()`, `cancelOrder()`, `deposit()`, `withdraw()`) are **never cached** to ensure data integrity.\n\n**Note:** A failed `Result` (`success === false`) is **never cached**, in any tier. A transient RPC or API failure is returned to the caller but the next call retries immediately instead of serving the failure for the rest of the TTL.\n\n**Note:** `getPortfolioBalance`, `getAllPortfolioBalances`, `getChainWalletBalance`, `getChainWalletBalances` and `getAllChainWalletBalances` are **not** cached in the TypeScript SDK; every call reads from the RPC.\n\n### Per-User Caching\n\nCached balance data is keyed by wallet address. When `address` is not provided, the SDK uses the connected wallet's address:\n\n```typescript\n// Each user gets their own cached balance data\nconst b1 = await client.getChainTokenBalances(\"Avalanche\", [\"AVAX\", \"USDC\"]); // Uses connected wallet\nconst b2 = await client.getChainTokenBalances(\"Avalanche\", [\"AVAX\", \"USDC\"], \"0xOtherUser\"); // Different cache entry\n```\n\n### Wallet Balance Results\n\nChain-wallet balance methods return entries of the shape\n`{ chain, symbol, balance, type }` (ERC20 entries also carry `address`).\n`balance` is always a numeric string on success. A lookup that fails (RPC error,\nchain not connected, unknown token) never puts an error string in `balance`:\n\n- `getChainWalletBalance(chain, token)` returns `Result.fail(<sanitized message>)`.\n- `getChainWalletBalances(chain)` and `getAllChainWalletBalances()` drop the failed\n  entry from `chain_balances` and append `\"<chain> <symbol>: <message>\"` to an\n  additional `errors` array. The `Result` is still `ok` when at least one lookup\n  succeeded, and `fail` only when every lookup failed.\n- `getChainTokenBalances(chain, tokens, address?)` fails the whole `Result` if any\n  requested token could not be read, so the returned map only ever holds numbers.\n\n```typescript\nconst result = await client.getAllChainWalletBalances();\nif (result.success) {\n    for (const entry of result.data!.chain_balances) {\n        console.log(entry.chain, entry.symbol, Number(entry.balance));\n    }\n    for (const problem of result.data!.errors) {\n        console.warn(\"skipped:\", problem); // e.g. \"Avalanche AVAX: Error fetching native balance: ...\"\n    }\n}\n```\n\nTolerated per-entry failures are logged at `warn` level.\n\n### Performance Impact\n\nExpected reduction in API calls:\n- **Static data**: ~99.9% fewer calls (1 call per hour vs. every request)\n- **Semi-static data**: ~95% fewer calls (1 call per 15 min vs. frequent polling)\n- **Balance data**: Significant reduction for applications polling balances\n- **Orderbook data**: Useful for multi-component applications\n\n## Configuration\n\nThe SDK uses a centralized configuration system (`DexalotConfig`) that supports multiple initialization methods.\n\n### Options\n\n| Option | Type | Default | Description |\n|--------|------|---------|-------------|\n| `parentEnv` | `string` | `\"fuji-multi\"` | Environment configuration (e.g., `production-multi-avax`, `fuji-multi`) |\n| `apiBaseUrl` | `string` | Auto-detected | Base URL for Dexalot API (derived from `parentEnv`) |\n| `privateKey` | `string` | `undefined` | Wallet private key for signing transactions |\n| `cacheEnabled` | `boolean` | `true` | Enable/disable all caching behavior |\n| `timeoutConnect` | `number` | `5` | Connect timeout in seconds (env parity with Python; axios uses read timeout as the request cap) |\n| `timeoutRead` | `number` | `30` | Read timeout in seconds (axios request timeout = this value × 1000 ms) |\n| `logLevel` | `string` | `\"info\"` | Logging verbosity (`debug`, `info`, `warn`, `error`) |\n| `logFormat` | `string` | `\"console\"` | Log output format (`console`, `json`) |\n| `connectionPoolLimit` | `number` | `100` | Total connection pool size across all hosts |\n| `connectionPoolLimitPerHost` | `number` | `30` | Maximum connections per individual host |\n\n### Retry Settings\n\n| Option | Type | Default | Description |\n|--------|------|---------|-------------|\n| `retryEnabled` | `boolean` | `true` | Enable/disable automatic retry |\n| `retryMaxAttempts` | `number` | `3` | Maximum number of retry attempts |\n| `retryInitialDelay` | `number` | `1` | Initial delay in seconds before first retry |\n| `retryMaxDelay` | `number` | `10` | Maximum delay in seconds between retries |\n| `retryExponentialBase` | `number` | `2.0` | Exponential backoff multiplier |\n| `retryOnStatus` | `number[]` | `[429, 500, 502, 503, 504]` | HTTP status codes that trigger retry |\n\n### Rate Limiting Settings\n\n| Option | Type | Default | Description |\n|--------|------|---------|-------------|\n| `rateLimitEnabled` | `boolean` | `true` | Enable/disable rate limiting |\n| `rateLimitRequestsPerSecond` | `number` | `5.0` | Maximum API requests per second |\n| `rateLimitRpcPerSecond` | `number` | `10.0` | Maximum RPC calls per second |\n\n### Nonce Manager Settings\n\n| Option | Type | Default | Description |\n|--------|------|---------|-------------|\n| `nonceManagerEnabled` | `boolean` | `true` | Enable/disable nonce manager (prevents race conditions) |\n\n### WebSocket Settings\n\n| Option | Type | Default | Description |\n|--------|------|---------|-------------|\n| `wsManagerEnabled` | `boolean` | `false` | Enable/disable WebSocket Manager (persistent connections) |\n| `wsPingInterval` | `number` | `30` | Seconds between ping messages |\n| `wsPingTimeout` | `number` | `10` | Seconds to wait for pong before reconnecting |\n| `wsReconnectInitialDelay` | `number` | `1` | Initial reconnect delay in seconds |\n| `wsReconnectMaxDelay` | `number` | `60` | Maximum reconnect delay in seconds |\n| `wsReconnectExponentialBase` | `number` | `2.0` | Exponential backoff multiplier |\n| `wsReconnectMaxAttempts` | `number` | `10` | Maximum reconnection attempts (0 = infinite) |\n\n### Precedence\n\nConfiguration values are resolved in the following order (highest to lowest priority):\n\n1. **Constructor Arguments**: Passed directly to `DexalotClient`\n   ```typescript\n   // 1. Highest Priority\n   const client = new DexalotClient(createConfig({ parentEnv: \"custom-env\" }));\n   ```\n\n2. **Environment Variables**: System-level variables\n   ```bash\n   # 2. High Priority\n   export DEXALOT_PARENT_ENV=\"production-multi-avax\"\n   ```\n\n3. **`.env` File**: Variables loaded from local `.env` file\n   ```ini\n   # 3. Medium Priority\n   DEXALOT_PARENT_ENV=fuji-multi\n   ```\n\n4. **Defaults**: Hardcoded SDK defaults (`fuji-multi`)\n\n### Advanced Configuration\n\nFor complex setups, you can pass a `DexalotConfig` object directly:\n\n```typescript\nimport DexalotClient, { createConfig } from 'dexalot-sdk';\n\nconst config = createConfig({\n    parentEnv: \"production-multi-subnet\",\n    timeoutConnect: 10,\n    timeoutRead: 60,\n    cacheEnabled: false\n});\n\nconst client = new DexalotClient(config);\n```\n\nSee `env.example` for all available configuration options.\n\n## Provider Failover\n\nThe SDK includes automatic RPC provider failover to improve reliability when a single RPC endpoint fails. This feature allows you to configure multiple RPC endpoints per chain, with automatic failover to backup providers when the primary provider fails.\n\n### Features\n\n- **Multiple Providers**: Configure multiple RPC endpoints per chain (primary + fallbacks)\n- **Fail-Fast Strategy**: Automatically switches to the next provider when the current one fails\n- **Health Tracking**: Tracks provider health (failure counts, last failure time)\n- **Automatic Recovery**: Failed providers are retried after a cooldown period\n- **Thread-Safe**: Concurrent operations are handled safely with async locks\n\n### Configuration\n\nProvider failover is **enabled by default**. You can configure it via environment variables or `DexalotConfig`:\n\n| Variable | Description | Default |\n|----------|-------------|---------|\n| `DEXALOT_PROVIDER_FAILOVER_ENABLED` | Enable/disable failover | `true` |\n| `DEXALOT_PROVIDER_FAILOVER_COOLDOWN` | Seconds before retrying failed provider | `60` |\n| `DEXALOT_PROVIDER_FAILOVER_MAX_FAILURES` | Max failures before marking provider unhealthy | `3` |\n\n### RPC Provider Override\n\nYou can override RPC endpoints for specific chains using environment variables. This is useful for:\n- Adding backup providers for redundancy\n- Using custom RPC endpoints\n- Testing with different providers\n\nTwo formats are supported:\n\n1. **Chain ID format (preferred)**: `DEXALOT_RPC_<CHAIN_ID>=url1,url2,url3`\n2. **Native token symbol format**: `DEXALOT_RPC_<NATIVE_TOKEN_SYMBOL>=url1,url2,url3`\n\nChain ID takes precedence over native token symbol if both are set. Examples:\n\n```bash\n# Chain ID format (preferred)\nDEXALOT_RPC_43114=https://api.avax.network/ext/bc/C/rpc,https://avalanche.public-rpc.com\nDEXALOT_RPC_1=https://eth.llamarpc.com,https://ethereum.public-rpc.com\nDEXALOT_RPC_42161=https://arb1.arbitrum.io/rpc\nDEXALOT_RPC_432204=https://subnets.avax.network/dexalot/mainnet/rpc\n\n# Native token symbol format (alternative)\nDEXALOT_RPC_AVAX=https://api.avax.network/ext/bc/C/rpc,https://avalanche.public-rpc.com\nDEXALOT_RPC_ETH=https://eth.llamarpc.com,https://ethereum.public-rpc.com\nDEXALOT_RPC_ALOT=https://subnets.avax.network/dexalot/mainnet/rpc\n```\n\n### How It Works\n\n1. **Provider Initialization**: When the client initializes, it loads RPC endpoints from:\n   - Environment variable overrides (if set)\n   - API response (from Dexalot API)\n   - Multiple URLs can be provided (comma-separated)\n\n2. **Failover Strategy**: When an RPC call fails:\n   - The failed provider is marked with a failure count\n   - The SDK automatically tries the next available provider\n   - If all providers fail, an error is raised\n\n3. **Health Tracking**: Each provider tracks:\n   - Failure count (incremented on each failure)\n   - Last failure time (for cooldown calculation)\n   - Health status (healthy/unhealthy)\n\n4. **Recovery**: After the cooldown period, failed providers can be retried. Providers are marked as unhealthy only after exceeding the max failure threshold.\n\n### Example\n\n```typescript\nimport DexalotClient, { createConfig } from 'dexalot-sdk';\n\n// Configure failover\nconst config = createConfig({\n    providerFailoverEnabled: true,\n    providerFailoverCooldown: 60,  // 60 seconds cooldown\n    providerFailoverMaxFailures: 3,   // Mark unhealthy after 3 failures\n});\n\nconst client = new DexalotClient(config);\nawait client.initializeClient();\n\n// RPC calls use failover automatically when the primary provider fails (if enabled)\n```\n\n### Provider failover behavior\n\n- With `providerFailoverEnabled: false`, only the primary RPC URL is used (no rotation).\n- When the API returns a single provider entry, the client uses that URL directly.\n- Environment variables can override failover settings as documented above.\n\n## Observability\n\nThe SDK includes a comprehensive instrumentation layer to track API operations, performance metrics, and WebSocket events.\n\n### Features\n\n- **Structured Logging**: Logs are output in JSON format (or plain text) with metadata.\n- **Performance Tracking**: Automatically tracks the duration of all core operations (`clob`, `swap`, `transfer`).\n- **Security**: Designed with privacy by default:\n  - **No Arguments**: Function arguments and return values are **never logged**.\n  - **No Payloads**: Transaction payloads and private keys are **never logged**.\n  - **Safe Defaults**: Minimal logging in production (`INFO`), detailed tracing only in `DEBUG`.\n\n### Configuration\n\nControl logging behavior using environment variables:\n\n| Variable | Description | Default | Values |\n|----------|-------------|---------|--------|\n| `DEXALOT_LOG_LEVEL` | Logging verbosity | `INFO` | `DEBUG`, `INFO`, `WARN`, `ERROR` |\n| `DEXALOT_LOG_FORMAT` | Log output format | `console` | `json`, `console` |\n\n### Instrumented Components\n\n- **CLOB**: Full coverage of Order Management (`add`/`cancel`/`replace`), Market Data (`orderbook`, `pairs`), and Account Data (`openOrders`).\n- **Swap**: RFQ operation lifecycle including Firm/Soft Quotes and Swap Execution.\n- **Transfer**: Cross-chain Bridge operations (`deposit`/`withdraw`), Portfolio Management (`transferPortfolio`), and comprehensive Balance queries.\n- **WebSocket**: Connection lifecycle events (`Open`/`Close`/`Error`) and message traffic (at `DEBUG` level).\n\n### Example Output\n\n```json\n{\n  \"timestamp\": \"2023-10-27T10:00:00Z\",\n  \"level\": \"INFO\",\n  \"logger\": \"dexalot_sdk.core.clob\",\n  \"message\": \"clob completed in 0.123s\",\n  \"extra_fields\": {\n    \"operation\": \"clob\",\n    \"function\": \"addOrder\",\n    \"duration\": 0.123,\n    \"status\": \"success\"\n  }\n}\n```\n\n## Resource Cleanup\n\nThe SDK manages several resources that need proper cleanup:\n- **HTTP sessions** (`axios` instances)\n- **Web3 provider sessions** (internal HTTP sessions)\n- **WebSocket connections** (if WebSocket manager is enabled)\n\n### Always Close the Client\n\nAlways call `await client.close()` when you're done with the client to ensure proper resource cleanup:\n\n```typescript\nasync function main() {\n    let client: DexalotClient | null = null;\n    try {\n        client = new DexalotClient();\n        await client.initializeClient();\n        \n        // Your operations here\n        const result = await client.getTokens();\n        if (result.success) {\n            console.log(`Tokens: ${result.data}`);\n        }\n    } finally {\n        // Always close the client in a finally block\n        if (client !== null) {\n            await client.close();\n        }\n    }\n}\n```\n\n**Note:** The async `close()` method:\n- Closes all HTTP sessions\n- Closes WebSocket connections (if enabled)\n- Resets rate limiters and nonce managers\n- Is safe to call multiple times (idempotent)\n\n## Async Usage\n\nThe SDK is **fully async** - all methods are `async` and must be awaited. This enables concurrent operations and better performance.\n\n### Script Usage\n\nFor standalone scripts, use `async/await`:\n\n```typescript\nimport DexalotClient from 'dexalot-sdk';\n\nasync function main() {\n    let client: DexalotClient | null = null;\n    try {\n        client = new DexalotClient();\n        await client.initializeClient();\n        \n        // Your async operations here\n        const result = await client.getTokens();\n        if (result.success) {\n            console.log(`Tokens: ${result.data}`);\n        }\n    } finally {\n        if (client !== null) {\n            await client.close();\n        }\n    }\n}\n\nmain().catch(console.error);\n```\n\n### Application Usage\n\nIn async applications (e.g., Node.js servers, async web frameworks), use `await` directly:\n\n```typescript\nimport DexalotClient from 'dexalot-sdk';\n\n// In Express.js or similar\nconst client = new DexalotClient();\n\n// Initialize on startup\nawait client.initializeClient();\n\n// Use in routes\napp.get('/tokens', async (req, res) => {\n    const result = await client.getTokens();\n    if (result.success) {\n        res.json(result.data);\n    } else {\n        res.status(500).json({ error: result.error });\n    }\n});\n\n// Close on shutdown\nprocess.on('SIGTERM', () => {\n    void client.close();\n});\n```\n\n### Parallel Operations\n\nThe async architecture enables parallel operations for better performance:\n\n```typescript\nimport DexalotClient from 'dexalot-sdk';\n\nasync function main() {\n    let client: DexalotClient | null = null;\n    try {\n        client = new DexalotClient();\n        await client.initializeClient();\n        \n        // Fetch multiple orderbooks in parallel\n        const pairs = [\"AVAX/USDC\", \"ALOT/USDC\", \"ETH/USDC\"];\n        const results = await Promise.all(\n            pairs.map(pair => client.getOrderBook(pair))\n        );\n        \n        results.forEach((result, index) => {\n            if (result.success) {\n                console.log(`${pairs[index]}: ${result.data.bids.length} bids`);\n            }\n        });\n    } finally {\n        if (client !== null) {\n            await client.close();\n        }\n    }\n}\n\nmain().catch(console.error);\n```\n\n## Error Handling\n\nThe SDK uses a `Result<T>` pattern for consistent error handling across all methods.\n\n### Result Pattern\n\nAll SDK methods return `Result<T>` with three fields:\n- `success: boolean` - True if operation succeeded\n- `data: T | null` - Result data on success, null on error\n- `error: string | null` - Error message on failure, null on success\n\n### Basic Error Handling\n\n```typescript\nconst result = await client.addOrder({\n    pair: \"AVAX/USDC\",\n    side: \"BUY\",\n    amount: 1.0,\n    price: 25.0\n});\n\nif (result.success) {\n    const txHash = result.data.txHash;\n    console.log(`Order placed: ${txHash}`);\n} else {\n    console.error(`Order failed: ${result.error}`);\n    // Handle error (retry, log, notify user, etc.)\n}\n```\n\n### Validation Errors\n\nInput validation errors are returned as `Result.fail()` with descriptive messages:\n\n```typescript\n// Invalid amount (negative)\nconst result = await client.addOrder({\n    pair: \"AVAX/USDC\",\n    side: \"BUY\",\n    amount: -1.0,  // Invalid!\n    price: 25.0\n});\n\nif (!result.success) {\n    // result.error will be: \"Invalid amount: must be positive (> 0), got -1.0\"\n    console.error(`Validation error: ${result.error}`);\n}\n```\n\n### Error Sanitization\n\nError messages are automatically sanitized to prevent information leakage:\n- File paths are removed\n- URLs are removed\n- Stack traces are removed\n- User-friendly messages are provided\n\n### Backend reason codes\n\nErrors from the Dexalot REST API now include structured `reasonCode` (e.g. `FQ-015`, `P-AFNE-02`, `T-TMDQ-01`, `RF-IMV-01`) and human `reason` fields. These are preserved verbatim in thrown errors and `Result.fail()` messages — you'll see `\"FQ-015: insufficient liquidity\"` rather than the generic `\"Request failed with status code 400\"`. Catch and pattern-match on the code prefix to react programmatically:\n\n```typescript\nconst result = await client.getSwapFirmQuote('USDC', 'AVAX', 100);\nif (!result.success && result.error.startsWith('FQ-')) {\n    // RFQ backend rejected the quote — see the reasonCode for why\n}\n```\n\n### Best Practices\n\n1. **Always check `result.success`** before accessing `result.data`\n2. **Handle errors appropriately** - log, retry, or notify users\n3. **Use descriptive error messages** - the SDK provides clear error messages\n4. **Don't expose internal errors** - error sanitization is automatic\n\n```typescript\nasync function placeOrderSafely(\n    client: DexalotClient,\n    pair: string,\n    side: string,\n    amount: number,\n    price: number\n) {\n    const result = await client.addOrder({ pair, side, amount, price });\n    \n    if (result.success) {\n        return { status: \"success\", txHash: result.data.txHash };\n    } else {\n        // Log error for debugging\n        console.error(`Order failed: ${result.error}`);\n        // Return user-friendly message\n        return { status: \"error\", message: \"Failed to place order. Please try again.\" };\n    }\n}\n```\n\n## Transaction Receipt Handling\n\nAll state-changing operations (placing orders, deposits, withdrawals, etc.) now support a `waitForReceipt` parameter that controls whether the SDK waits for blockchain transaction confirmation before returning.\n\n### Default Behavior\n\nBy default, **all state-changing operations wait for transaction receipts** (`waitForReceipt=true`). This ensures:\n- Transactions are confirmed on-chain before the method returns\n- Transaction failures are detected immediately\n- More reliable operation results\n\n### Usage\n\n```typescript\n// Default behavior: waits for receipt (recommended)\nconst result = await client.addOrder({\n    pair: \"AVAX/USDC\",\n    side: \"BUY\",\n    amount: 1.0,\n    price: 25.0\n});\n// Method returns only after transaction is confirmed\n\n// Explicitly wait for receipt\nconst result = await client.addOrder({\n    pair: \"AVAX/USDC\",\n    side: \"BUY\",\n    amount: 1.0,\n    price: 25.0,\n    waitForReceipt: true\n});\n\n// Don't wait for receipt (returns immediately after sending)\nconst result = await client.addOrder({\n    pair: \"AVAX/USDC\",\n    side: \"BUY\",\n    amount: 1.0,\n    price: 25.0,\n    waitForReceipt: false\n});\n// Method returns immediately with transaction hash\n// Transaction may still be pending\n```\n\n### When to Use `waitForReceipt=false`\n\nUse `waitForReceipt=false` when:\n- **Batch operations**: Sending many transactions and want to submit them quickly\n- **Fire-and-forget**: You don't need immediate confirmation\n- **Custom polling**: You'll check transaction status yourself\n\n**Important**: When `waitForReceipt=false`, the SDK returns immediately after broadcasting the transaction. You should:\n- Check transaction status yourself using the returned `txHash`\n- Handle potential transaction failures in your application logic\n- Be aware that the transaction may still be pending when the method returns\n\n### Affected Methods\n\nAll state-changing methods support `waitForReceipt`:\n\n**CLOB Operations:**\n- `addOrder({ pair, side, amount, price, type?, waitForReceipt? })`\n- `addOrderList(orders, waitForReceipt?)`\n- `cancelOrder(orderId, waitForReceipt?)`\n- `cancelListOrders(orderIds, waitForReceipt?)`\n- `cancelListOrdersByClientId(clientOrderIds, waitForReceipt?)`\n- `replaceOrder(orderId, newPrice, newAmount, waitForReceipt?)`\n- `cancelAddList(replacements, waitForReceipt?)`\n\n**Transfer Operations:**\n- `deposit(token, amount, sourceChain, useLayerZero?, waitForReceipt?)`\n- `withdraw(token, amount, destinationChain, useLayerZero?, waitForReceipt?)`\n- `addGas(amount, waitForReceipt?)`\n- `removeGas(amount, waitForReceipt?)`\n- `transferPortfolio(token, amount, toAddress, waitForReceipt?)`\n\n**Swap Operations:**\n- `executeRFQSwap(quote, waitForReceipt?)`\n- `approveRfqMaker(quote, amountWei?, waitForReceipt?)`\n\n**RFQ execution target.** Firm quotes are served by several maker contracts\n(the legacy `MainnetRFQ` plus `DexalotRFQ` instances) behind the\n`DexalotRouter`, and each maker verifies its own signer. `executeRFQSwap`\ntherefore sends `simpleSwap` to the quote's `tx.to` (the router) or, when the\nquote carries no `tx`, to `order.maker` directly. It never uses the\n`MainnetRFQ` address from the deployments endpoint as the target. The router\naddress comes from the deployments endpoint (`DexalotRouter`), falling back to\n`MainnetRFQ.trustedForwarder()` on-chain; the makers come from the router's\n`getAllowedRFQs()`. Before broadcasting it checks that `order.maker` is on that\nallow-list, that `tx.to` is the router or the maker, and that any `tx.data` /\n`tx.value` in the quote match the call the SDK encodes itself. Errors carry a\n`[target=..., maker=..., quoteId=..., nonceAndMeta=..., expiry=...]` suffix.\n\n**ERC20 sells need a per-maker allowance.** The maker contract pulls the taker\nasset with `transferFrom`, so the allowance must be granted to `order.maker`,\nnot to the router and not to the legacy address. `executeRFQSwap` fails fast\nwith an actionable message when the allowance is short; call\n`approveRfqMaker(quote)` first. Native-asset sells (AVAX) need no approval.\n\n### Example: Batch Order Placement\n\n```typescript\n// Place multiple orders without waiting for each receipt\nconst orders = [\n    { pair: \"AVAX/USDC\", side: \"BUY\", amount: 1.0, price: 25.0 },\n    { pair: \"AVAX/USDC\", side: \"BUY\", amount: 2.0, price: 24.0 },\n    { pair: \"AVAX/USDC\", side: \"SELL\", amount: 1.0, price: 26.0 },\n];\n\n// Submit all orders quickly without waiting\nconst result = await client.addOrderList(orders, false);\nif (result.success) {\n    const txHash = result.data.txHash;\n    // Check status later\n    // await checkTransactionStatus(txHash);\n}\n```\n\n### Example: Fire-and-Forget Deposit\n\n```typescript\n// Submit deposit and continue with other operations\nconst result = await client.deposit(\"AVAX\", 1.0, \"Avalanche\", false, false);\nif (result.success) {\n    const txHash = result.data; // Just the transaction hash\n    // Continue with other operations\n    // Monitor deposit status separately\n}\n```\n\n### Canonical Order Model\n\nOrder reads (`getOpenOrders`, `getOrder`, `getOrderByClientId`) return one canonical order object regardless of whether the source was the REST API or the contract:\n\n- `internalOrderId`, `clientOrderId`, `tradePairId`, `pair`\n- `price`, `totalAmount`, `quantity`, `quantityFilled`, `totalFee`\n- `traderAddress`, `side`, `type1`, `type2`, `status`\n- `updateBlock`, `createBlock`, `createTs`, `updateTs`, `tx`\n\nEnum-style fields are normalized to human-readable strings such as `BUY`, `SELL`, `LIMIT`, `GTC`, and `FILLED`. Contract-backed reads return `createBlock` and `updateBlock` as JavaScript numbers, not hex strings. API-backed open orders may return those block fields as `null` when the Dexalot API omits them, while still preserving `createTs`, `updateTs`, and `tx`.\n\n## API Field Name Standardization\n\nThe SDK automatically standardizes API response field names to match TypeScript naming conventions (camelCase). This ensures consistent field names regardless of API response format variations.\n\n### Standardized Fields\n\n**Orders API:**\n- `internalOrderId` (from `id`)\n- `clientOrderId` (from `clientordid`, `client_order_id`)\n- `tradePairId` (from `tradePairId`, `tradepairid`, `trade_pair_id`, or derived from `pair`)\n- `pair`, `price`, `quantity`, `quantityFilled`, `totalAmount`, `totalFee`\n- `traderAddress`, `side`, `type1`, `type2`, `status`\n- `createBlock`, `updateBlock`, `createTs`, `updateTs`, `tx`\n\nOrders are normalized into one canonical SDK shape across REST and contract order reads.\n\n**Environments API:**\n- `chainId` (from `chainid`, `chain_id`)\n- `envType` (from `type`, `env_type`)\n- `rpc` (from `chain_instance`)\n- `network` (from `chain_display_name`)\n\n**Tokens API:**\n- `evmDecimals` (from `evmdecimals`, `evm_decimals`, `decimals`)\n- `chainId` (from `chainid`, `chain_id`)\n- `network` (from `chain_display_name`)\n\n**Pairs API:**\n- `base_decimals`, `quote_decimals`\n- `base_display_decimals`, `quote_display_decimals`\n- `min_trade_amount`, `max_trade_amount`\n\n**RFQ Quotes API:**\n- `chainId` (from `chainid`, `chain_id`)\n- `secureQuote` (from `securequote`, `secure_quote`)\n- `quoteId` (from `quoteid`, `quote_id`)\n- Nested order data: `nonceAndMeta`, `makerAsset`, `takerAsset`, `makerAmount`, `takerAmount`\n\n**Deployment API:**\n- `env`, `address`, `abi` (handles variations like `Env`, `Address`, `Abi`)\n\n**Price History API (`getTokenPriceHistory`, `getTokenHourlyPriceHistory`):**\n- `timestamp` (from `date` ISO-8601, `ts`, `timestamp`, `time` — ms auto-detected by magnitude and divided to seconds)\n- `price` (from string decimal, coerced to number; scientific notation supported)\n\n**Combined Transfers API (`getCombinedTransfers`):**\n- The canonical `Transfer` shape exposes camelCase fields normalized from the backend's snake_case `DBTransfer`: `actionType`, `status`, `symbol`, `quantity`, `fee`, `traderAddress`, `bridge`, `bridgeUrl`, `nonce`, `sourceEnv`, `sourceChainId`, `sourceTx`, `sourceTs`, `targetEnv`, `targetChainId`, `targetTx`, `targetTs`.\n- Numeric enums are mapped to string labels: `status` (`COMPLETED`/`INFLIGHT`/`DELAYED`), `actionType` (10 labels including `WITHDRAWN`/`DEPOSITED`/`SENT`/`RECEIVED`/`RECOVERED`/`ADD_GAS`/`REMOVE_GAS`/`AUTO_FILL`/`WITHDRAW_PENDING`/`DEPOSIT_PENDING`), `bridge` (`NATIVE`/`LAYER0`/`CELER`/`ICM`).\n- Quantity and fee arrive as display-decimal Big-strings — no wei→human decode needed (parsed via `Number()`).\n- Timestamps are normalized to unix **seconds** (UTC) **numbers** (the backend emits ISO-8601 strings, which are coerced via `Date.parse`): `sourceTs` is always present (`0` sentinel when missing), and `targetTs` is `null` when there is no target leg. The other target fields (`targetEnv`, `targetChainId`, `targetTx`) are likewise `null` for transfers that never cross.\n\n**Order History API (`getOrderHistory`):**\n- Same canonical `Order` shape and aliases as `getOpenOrders` — see the \"Canonical Order Model\" section above.\n\n### Benefits\n\n- **Consistent interface**: Field names are exposed in camelCase in TypeScript.\n- **Alias handling**: Common snake_case and alternate keys from the API are normalized automatically.\n\nAll API responses are automatically transformed before being returned, so you can always rely on standardized field names.\n\n## Reliability Features\n\nThe SDK includes several reliability features that work automatically to improve stability and performance.\n\n### Retry Mechanism\n\nAutomatic retry with exponential backoff for transient failures:\n\n- **Default**: 3 attempts with exponential backoff (1s, 2s, 4s)\n- **Retries on**: HTTP 429, 500, 502, 503, 504 and network errors\n- **Configurable**: Via `DexalotConfig` or environment variables\n\n```typescript\nimport DexalotClient, { createConfig } from 'dexalot-sdk';\n\n// Custom retry configuration\nconst config = createConfig({\n    retryEnabled: true,\n    retryMaxAttempts: 5,\n    retryInitialDelay: 2000,  // Start with 2s delay\n    retryMaxDelay: 30000,      // Max 30s between retries\n    retryExponentialBase: 2.0\n});\n\nconst client = new DexalotClient(config);\n```\n\n### Rate Limiting\n\nToken bucket rate limiter prevents API throttling:\n\n- **Default**: 5 requests/second for API, 10 requests/second for RPC\n- **Automatic**: Applied to all HTTP and RPC calls\n- **Configurable**: Via `DexalotConfig` or environment variables\n\n```typescript\nconst config = createConfig({\n    rateLimitEnabled: true,\n    rateLimitRequestsPerSecond: 10.0,  // 10 API calls/second\n    rateLimitRpcPerSecond: 20.0         // 20 RPC calls/second\n});\n```\n\n### Nonce Manager\n\nAutomatic nonce management prevents transaction race conditions:\n\n- **Automatic**: Tracks nonces per (chain_id, address) combination\n- **Thread-safe**: Uses async locks for concurrent transactions\n- **Default-on**: No manual nonce bookkeeping for normal use\n\nThe nonce manager is enabled by default and works automatically. It:\n1. Fetches the current nonce from the chain on first use\n2. Tracks nonces locally for subsequent transactions\n3. Automatically increments nonces for each transaction\n4. Prevents race conditions in concurrent scenarios\n\n```typescript\n// Nonce manager works automatically - no configuration needed\n// For high-concurrency scenarios, it's already handling nonces correctly\n\n// Multiple transactions can be sent concurrently\nconst tasks = [\n    client.addOrder({ pair: \"AVAX/USDC\", side: \"BUY\", amount: 1.0, price: 25.0 }),\n    client.addOrder({ pair: \"ALOT/USDC\", side: \"BUY\", amount: 10.0, price: 0.5 }),\n    client.deposit(\"AVAX\", 1.0)\n];\nconst results = await Promise.all(tasks);\n// Nonce manager ensures correct nonce ordering\n```\n\n### Provider Failover\n\nAutomatic RPC provider failover (see [Provider Failover](#provider-failover) section above).\n\n## WebSocket Manager\n\nThe SDK includes a persistent WebSocket manager for long-running subscriptions with automatic reconnection and heartbeat.\n\n### Features\n\n- **Persistent Connections**: Single connection for multiple subscriptions\n- **Multiple Subscriptions**: Subscribe to multiple topics with individual callbacks\n- **Automatic Reconnection**: Exponential backoff reconnection on failures\n- **Heartbeat Monitoring**: Ping/pong mechanism to detect dead connections\n- **Thread-Safe**: Safe for concurrent use\n\n### Basic Usage\n\n```typescript\nimport DexalotClient, { createConfig } from 'dexalot-sdk';\n\nasync function main() {\n    let client: DexalotClient | null = null;\n    try {\n        const config = createConfig({\n            wsManagerEnabled: true\n        });\n        client = new DexalotClient(config);\n        await client.initializeClient();\n        \n        // Subscribe to orderbook updates\n        const onOrderbookUpdate = (message: any) => {\n            console.log(`Orderbook update: ${JSON.stringify(message)}`);\n        };\n        \n        await client.subscribeToEvents(\n            \"orderbook.AVAX/USDC\",\n            onOrderbookUpdate,\n            false\n        );\n        \n        // Subscribe to private order updates\n        const onOrderUpdate = (message: any) => {\n            console.log(`Order update: ${JSON.stringify(message)}`);\n        };\n        \n        await client.subscribeToEvents(\n            \"orders\",\n            onOrderUpdate,\n            true\n        );\n        \n        // Keep connection alive\n        await new Promise(resolve => setTimeout(resolve, 60000));\n        \n        // Unsubscribe when done\n        await client.unsubscribeFromEvents(\"orderbook.AVAX/USDC\");\n    } finally {\n        // Always close the client to clean up WebSocket and HTTP sessions\n        if (client !== null) {\n            await client.close();\n        }\n    }\n}\n\nmain().catch(console.error);\n```\n\n### Configuration\n\n```typescript\nimport DexalotClient, { createConfig } from 'dexalot-sdk';\n\nconst config = createConfig({\n    wsManagerEnabled: true,\n    wsPingInterval: 30,        // Ping every 30 seconds\n    wsPingTimeout: 10,         // Wait 10s for pong before reconnecting\n    wsReconnectInitialDelay: 1,\n    wsReconnectMaxDelay: 60,\n    wsReconnectExponentialBase: 2.0,\n    wsReconnectMaxAttempts: 10  // 0 = infinite retries\n});\n\nconst client = new DexalotClient(config);\n```\n\n## Input Validation\n\nThe SDK automatically validates all input parameters before processing operations. This prevents invalid data from reaching the blockchain or API. Validation is implemented in `utils/input_validators.ts` and returns `Result<null>` for consistent error handling.\n\n### Automatic Validation\n\nInput validation is applied to all critical methods:\n\n- **CLOB Operations**: `addOrder()`, `cancelOrder()`, `getOrderBook()`, etc.\n- **Swap Operations**: `executeRfqSwap()`, `getSwapFirmQuote()`, etc.\n- **Transfer Operations**: `deposit()`, `withdraw()`, `transferPortfolio()`, etc.\n\n### Validation Rules\n\n- **Amounts**: Must be positive, finite numbers (not NaN or infinite)\n- **Prices**: Must be positive, finite numbers\n- **Addresses**: Must be valid Ethereum addresses (0x prefix, 42 chars, hex)\n- **Pairs**: Must be in `TOKEN/TOKEN` format\n- **Order IDs**: Must be valid hex strings or bytes32 format\n- **Token Symbols**: Must be non-empty, alphanumeric strings\n\n### Handling Validation Errors\n\nValidation errors are returned as `Result.fail()` with descriptive messages:\n\n```typescript\n// Invalid amount\nconst result = await client.addOrder({\n    pair: \"AVAX/USDC\",\n    side: \"BUY\",\n    amount: -1.0,  // Invalid: negative amount\n    price: 25.0\n});\n\nif (!result.success) {\n    // result.error: \"Invalid amount: must be positive (> 0), got -1.0\"\n    console.error(result.error);\n}\n\n// Invalid address\nconst balanceResult = await client.getPortfolioBalance(\n    \"USDC\",\n    \"invalid\"  // Not a valid Ethereum address\n);\nif (!balanceResult.success) {\n    // result.error: \"Invalid address: must be a valid Ethereum address (0x prefix, 42 chars, hex)\"\n    console.error(balanceResult.error);\n}\n```\n\n### Common Validation Errors\n\n| Error | Cause | Solution |\n|-------|-------|----------|\n| \"Invalid amount: must be positive\" | Negative or zero amount | Use positive values |\n| \"Invalid address: must be a valid Ethereum address\" | Invalid address format | Use 0x-prefixed hex addresses |\n| \"Invalid pair: must be in TOKEN/TOKEN format\" | Invalid pair format | Use format like \"AVAX/USDC\" |\n| \"Invalid order_id: must be hex string or bytes32\" | Invalid order ID | Use valid hex string |\n\nValidation happens before any network calls, so invalid inputs fail fast with clear error messages.\n","readmeFilename":"README.md"}