{"_id":"@casper-ecosystem/odra-js-client","name":"@casper-ecosystem/odra-js-client","dist-tags":{"latest":"1.0.0"},"versions":{"1.0.0":{"name":"@casper-ecosystem/odra-js-client","version":"1.0.0","license":"Apache-2.0","description":"JavaScript/TypeScript utilities for interacting with Odra smart contracts on the Casper Network","main":"dist/index.js","types":"dist/index.d.ts","publishConfig":{"access":"public"},"repository":{"type":"git","url":"git+https://github.com/casper-ecosystem/odra-js-client.git"},"homepage":"https://github.com/casper-ecosystem/odra-js-client#readme","bugs":{"url":"https://github.com/casper-ecosystem/odra-js-client/issues"},"scripts":{"build":"tsc","clean":"rm -rf ./dist","test":"cross-env NODE_ENV=test TS_NODE_FILES=true mocha --require ts-node/register/transpile-only --extension ts \"src/tests/**/*.test.ts\"","format":"prettier --write \"src/**/*.ts\"","format:check":"prettier --check \"src/**/*.ts\"","prepublishOnly":"npm test && npm run build"},"keywords":["Casper","Odra","blockchain","sdk"],"peerDependencies":{"casper-js-sdk":"^5.0.0"},"devDependencies":{"@types/chai":"^4.1.7","@types/mocha":"^5.2.7","@types/node":"^14.14.31","casper-js-sdk":"^5.0.11","chai":"^4.2.0","cross-env":"^7.0.3","mocha":"^10.1.0","prettier":"^3.8.1","ts-node":"^10.9.2","typescript":"^6.0.2"},"gitHead":"1b1aa64cbd596f0e967a3d534ccc011d4cadb7ae","_id":"@casper-ecosystem/odra-js-client@1.0.0","_nodeVersion":"18.14.2","_npmVersion":"9.5.0","dist":{"integrity":"sha512-g7uiqfqL3xxRCmVgq5qVeRXcOd16RsSG7uNp+BrLgaJJylcJpTSJXdUy+EHhiKnpkRqQOB0onIN0NKC48uZiDg==","shasum":"631d2230c5417d612bf9486889a8e034e16838bf","tarball":"https://registry.npmjs.org/@casper-ecosystem/odra-js-client/-/odra-js-client-1.0.0.tgz","fileCount":19,"unpackedSize":87916,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQCYxzhf+fzmH2a/DI/ZrmjmK/+ROKul3V1eYQsUn2jCYwIhAKHHUuIKxHA+0sDPovUiSEZ0sXg7bIqaejnVuTHf+GY1"}]},"_npmUser":{"name":"alex_myshchyshyn","email":"oleksandrm@make.services"},"directories":{},"maintainers":[{"name":"michaelsteuer","email":"michael@make.services"},{"name":"make.services","email":"david.hernando@make.services"},{"name":"burlachenko","email":"ihor.burlachenko@gmail.com"},{"name":"alex_myshchyshyn","email":"oleksandrm@make.services"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/odra-js-client_1.0.0_1775765352066_0.2564184134635048"},"_hasShrinkwrap":false}},"time":{"created":"2026-04-09T20:09:11.977Z","1.0.0":"2026-04-09T20:09:12.213Z","modified":"2026-04-09T20:09:12.476Z"},"maintainers":[{"name":"michaelsteuer","email":"michael@make.services"},{"name":"make.services","email":"david.hernando@make.services"},{"name":"burlachenko","email":"ihor.burlachenko@gmail.com"},{"name":"alex_myshchyshyn","email":"oleksandrm@make.services"}],"description":"JavaScript/TypeScript utilities for interacting with Odra smart contracts on the Casper Network","homepage":"https://github.com/casper-ecosystem/odra-js-client#readme","keywords":["Casper","Odra","blockchain","sdk"],"repository":{"type":"git","url":"git+https://github.com/casper-ecosystem/odra-js-client.git"},"bugs":{"url":"https://github.com/casper-ecosystem/odra-js-client/issues"},"license":"Apache-2.0","readme":"# @casper-ecosystem/odra-js-client\n\n<p>\n  <a href=\"https://www.npmjs.com/package/%40casper-ecosystem%2Fodra-js-client\"><img src=\"https://img.shields.io/npm/v/%40casper-ecosystem%2Fodra-js-client?color=crimson&label=npm\" alt=\"npm version\" /></a>\n  <a href=\"https://www.npmjs.com/package/casper-js-sdk\"><img src=\"https://img.shields.io/npm/dependency-version/%40casper-ecosystem%2Fodra-js-client/peer/casper-js-sdk?color=blue&label=casper-js-sdk\" alt=\"casper-js-sdk peer\" /></a>\n  <img src=\"https://img.shields.io/badge/TypeScript-5-3178C6?logo=typescript&logoColor=white\" alt=\"TypeScript\" />\n  <img src=\"https://img.shields.io/badge/Casper-Network-FF4136?logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzMiAzMiI+PC9zdmc+\" alt=\"Casper\" />\n  <a href=\"https://github.com/casper-ecosystem/odra-js-client/blob/main/LICENSE\"><img src=\"https://img.shields.io/badge/license-Apache%202.0-green\" alt=\"license\" /></a>\n</p>\n\nJavaScript/TypeScript utilities for interacting with [Odra](https://odra.dev) smart contracts on the Casper Network.\n\nBuilt on top of [`casper-js-sdk`](https://github.com/casper-ecosystem/casper-js-sdk).\n\n---\n\n## Installation\n\n```bash\nnpm install @casper-ecosystem/odra-js-client casper-js-sdk\n```\n\n---\n\n## Quick start\n\n```ts\nimport { OdraClient } from '@casper-ecosystem/odra-js-client';\nimport { Args, CLValue } from 'casper-js-sdk';\nimport { readFileSync } from 'fs';\n\nconst client = new OdraClient(\n  'http://<Node Address>:7777/rpc',\n  'casper-test'\n);\n\nclient.setContractHash(\n  '834d3e29...', // bare hex, \"contract-hash-...\", or \"hash-...\" all accepted\n  'f1127fd1...', // contract package hash (required for write operations)\n);\n\n// Read a Var<T> field\nconst name = await client.getVar('name');\nconsole.log(name?.toString()); // e.g. \"MyToken\"\n\n// Read a Mapping<K, V> entry\nconst balance = await client.getMappingItem('balances', 'account-hash-abc...');\n\n// Call a non-payable entry point\nawait client.call(\n  'transfer',\n  Args.fromMap({\n    recipient: CLValue.newCLString('account-hash-...'),\n    amount: CLValue.newCLUInt256('1000000000'),\n  }),\n  {\n    sender: publicKey,\n    paymentAmount: '2500000000',\n    signingKeys: [privateKey],\n  },\n);\n\n// Call a payable entry point via the Odra proxy WASM\nconst proxyWasm = new Uint8Array(readFileSync('proxy_caller.wasm'));\n\nawait client.callPayable(\n  'stake',\n  Args.fromMap({}),\n  '2000000000000', // amount in motes\n  proxyWasm,\n  {\n    sender: publicKey,\n    paymentAmount: '5000000000',\n    signingKeys: [privateKey],\n  },\n);\n```\n\n---\n\n## API\n\n### `OdraClient`\n\nHigh-level client. Wraps all utilities into a single class.\n\n| Method                                                     | Description                                                                      |\n| ---------------------------------------------------------- | -------------------------------------------------------------------------------- |\n| `setContractHash(hash, packageHash?)`                      | Configure target contract. Accepts bare hex or prefixed strings. Returns `this`. |\n| `resolveContractHash()`                                    | Auto-resolve and cache the latest contract hash from the package hash.           |\n| `getNamedKeys()`                                           | List all named keys on the contract.                                             |\n| `getVar(name)`                                             | Read an Odra `Var<T>` field by named key name.                                   |\n| `getMappingItem(name, key)`                                | Read one entry from an Odra `Mapping<K,V>` dictionary.                           |\n| `getState(index, key?, blockHeight?)`                      | Read raw bytes from Odra's internal `state` dictionary by field index.           |\n| `call(entryPoint, args, params)`                           | Submit a non-payable contract call transaction.                                  |\n| `callPayable(entryPoint, innerArgs, amount, wasm, params)` | Submit a payable call via the Odra proxy WASM pattern.                           |\n\n---\n\n### `OdraStateDecoder`\n\nSequential byte-stream decoder for packed Odra struct state.\n\nOdra stores every `Var<T>` / `Mapping<K,V>` value as Casper-serialised bytes inside a `List<U8>` CLValue. The decoder skips the 4-byte count prefix automatically.\n\n> **Fields must be read in the same order they are declared in the Rust struct.** Reading out of order will silently produce incorrect values.\n\n```ts\nimport { getOdraState, OdraStateDecoder } from '@casper-ecosystem/odra-js-client';\nimport { RpcClient, HttpHandler } from 'casper-js-sdk';\n\nconst rpc = new RpcClient(new HttpHandler('http://<Node Address>:7777/rpc'));\nconst raw = await getOdraState(rpc, contractHash, BONDING_CURVE_INDEX, tokenKey);\nconst dec = new OdraStateDecoder(raw);\n\nconst csprReserve = dec.readU256();\nconst initialPrice = dec.readU256();\nconst graduated = dec.readBool();\nconst graduatedAt = dec.readOptionU64(); // bigint | null\n```\n\n| Method               | CL type              | Return                  |\n| -------------------- | -------------------- | ----------------------- |\n| `readBool()`         | `Bool`               | `boolean`               |\n| `readU8()`           | `U8`                 | `number`                |\n| `readU32()`          | `U32`                | `number`                |\n| `readU64()`          | `U64`                | `bigint`                |\n| `readU128()`         | `U128`               | `bigint`                |\n| `readU256()`         | `U256`               | `bigint`                |\n| `readU512()`         | `U512`               | `bigint`                |\n| `readString()`       | `String`             | `string`                |\n| `readKey()`          | `Key`                | `string` (prefixed)     |\n| `readKeyBytes()`     | `Key`                | `Uint8Array` (33 bytes) |\n| `readOption(fn)`     | `Option<T>`          | `T \\| null`             |\n| `readOptionU64()`    | `Option<U64>`        | `bigint \\| null`        |\n| `readOptionU256()`   | `Option<U256>`       | `bigint \\| null`        |\n| `readOptionString()` | `Option<String>`     | `string \\| null`        |\n| `readFixedBytes(n)`  | `ByteArray(N)`       | `Uint8Array`            |\n| `readBytes()`        | `Bytes` / `List<U8>` | `Uint8Array`            |\n\n---\n\n### Proxy call utilities\n\n```ts\nimport { isOdraProxyCall, parseOdraProxyCallArgs, buildOdraProxyCallArgs } from '@casper-ecosystem/odra-js-client';\n\n// Detect an Odra proxy call in a transaction scanner\nif (isOdraProxyCall(tx.payload.fields.args)) {\n  const { packageHash, entryPoint, innerArgs, amount } = parseOdraProxyCallArgs(\n    tx.payload.fields.args,\n  );\n}\n\n// Build outer args for a proxy WASM transaction\nconst outerArgs = buildOdraProxyCallArgs(\n  packageHashHex,\n  'stake',\n  innerArgs,\n  '2000000000000', // omit for non-payable\n);\n```\n\n---\n\n### Low-level state helpers\n\n```ts\nimport {\n  getOdraContractNamedKeys,\n  getOdraContractVar,\n  getOdraContractMappingItem,\n  getOdraState,\n  deriveOdraStateKey,\n  getContractHashFromPackage,\n} from '@casper-ecosystem/odra-js-client';\n```\n\n---\n\n## Payable entry points - how it works\n\nOdra payable entry points require a **Session transaction** (inline WASM) instead of a standard contract call. This is because `StoredVersionedContractByPackageHash` cannot transfer CSPR from the caller's main purse to the contract's purse.\n\nThe proxy WASM accepts:\n\n| Arg              | CL type         | Description                                                |\n| ---------------- | --------------- | ---------------------------------------------------------- |\n| `package_hash`   | `ByteArray(32)` | Target contract package hash                               |\n| `entry_point`    | `String`        | Entry point name                                           |\n| `args`           | `List<U8>`      | Casper-serialised inner `Args`                             |\n| `attached_value` | `U512`          | Amount the contract reads via `env().attached_value()`     |\n| `amount`         | `U512`          | Amount the Casper node uses to perform the actual transfer |\n\n> `amount` and `attached_value` carry the same mote value but serve different purposes.\n\n---\n\n## Development\n\n```bash\nnpm install\nnpm test       # run unit tests\nnpm run build  # compile to dist/\n```\n\n---\n\n## License\n\n[Apache 2.0](LICENSE)\n","readmeFilename":"README.md","_rev":"1-5558f1fd05f1d62678dcc98fce470441"}