-
Notifications
You must be signed in to change notification settings - Fork 64
Renderers py #651
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
Closed
Renderers py #651
Changes from all commits
Commits
Show all changes
86 commits
Select commit
Hold shift + click to select a range
19f7daf
renderers-py init
daog1 f33cf11
gen accounts
daog1 4fff987
gen types
daog1 9a146f7
gen ixs
daog1 1e466f0
gen ixs
daog1 829c28a
gen ixs
daog1 b193379
gen ixs
daog1 156c5dc
gen ixs
daog1 06d9025
fix gen array pubkey
daog1 6248388
fix gen types
daog1 146949b
fix gen types
daog1 2f17af1
fix gen types
daog1 7e3034c
fix gen types
daog1 3224762
add string
daog1 1570e28
fix args
daog1 fe281e5
fmt
daog1 2a97245
add gen enum
daog1 932f4aa
add gen enum
daog1 89ca36f
fix gen enum
daog1 f5d586e
add gen option
daog1 2fd2b1a
add gen visitFixedSizeType
daog1 9f02bf5
add fieldsdecode
daog1 29562af
fix types import types
daog1 205368c
add enumhelper
daog1 923138f
add enumhelper add imports
daog1 1b312e5
lint fix
daog1 727c589
add enumHelper
daog1 639ae33
add to_encodable
daog1 14fe724
fix enum struct
daog1 2b31571
fix enum
daog1 6e1bbae
fix None
daog1 a10cf9e
fix line
daog1 23260d7
lint fix
daog1 fd218cd
add seeds
daog1 4b2c884
add seeds
daog1 4b348c0
add seeds
daog1 3e7475b
gen errors
daog1 3b744df
lint fix
daog1 bea7efd
fix fromDecode
daog1 5c4c33b
fix layout.build encodable
daog1 0121705
Code cleanup
daog1 e6b5dec
fix enum
daog1 446fd14
fix enum
daog1 0551fd8
fix SolPubkey
daog1 865b6a5
lint:fix
daog1 09c862d
del ix RENT
daog1 199a45d
add dynamic discriminator
daog1 72bd669
add test
daog1 62dcb95
fix b 0x03
daog1 797bd84
add enum u32
daog1 4d059ea
fix imports
daog1 3521958
add Discriminator u64
daog1 3a0abd3
add e2e shared
daog1 329b485
fix visitSizePrefixType prefix 64
daog1 319e669
fix visitSizePrefixType prefix 64
daog1 f391ace
add throw UNSUPPORTED_NODE
daog1 8fd4c1c
add test hidden type
daog1 cf18cfd
add README
daog1 6824d66
add README
daog1 5eb0da4
fix extension.py
daog1 ea5cff6
fix extension.py
daog1 c9335a6
fix enum
daog1 1692603
fix enum
daog1 ebd6901
add types
daog1 dbf835c
add extension.py
daog1 5ca8e6d
fix types
daog1 9cb1c6d
add types
daog1 b853a8c
add types
daog1 e135e03
add types f32 f64
daog1 c2c4213
add types SizePrefix
daog1 335a9cb
add PROGRAM_ADDRESS
daog1 0842e4f
console
daog1 17c0f48
add types test
daog1 435bc0a
feat(renderers-py): Add support for constant value nodes and improve …
daog1 601b9f7
feat(solders): Add Pubkey handling and ZeroableOption refactor
daog1 3235df3
fix types PreOffset
daog1 c6ac5f4
add types test
daog1 0d87a71
fix types test
daog1 5ec346d
fix types test
daog1 3e1788e
Code cleanup
daog1 de14fdc
fix conflicts
daog1 1551eab
fix conflicts
daog1 d854bd1
fix conflicts
daog1 66d8755
fix conflicts
daog1 1349ca4
Code optimization,fix errors
daog1 0f9ffcb
Remove the dependency on the Solana codec package from the renderers-…
daog1 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,6 +2,7 @@ | |
|
|
||
| # dependencies | ||
| node_modules | ||
| dist | ||
| .pnp | ||
| .pnp.js | ||
|
|
||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,41 +1,41 @@ | ||
| { | ||
| "name": "codama-monorepo", | ||
| "private": true, | ||
| "scripts": { | ||
| "build": "turbo run build --log-order grouped", | ||
| "lint": "turbo run lint --log-order grouped", | ||
| "lint:fix": "turbo lint:fix --log-order grouped && pnpm prettier --log-level warn --ignore-unknown --write '{.,!packages}/*'", | ||
| "test": "turbo run test --log-order grouped", | ||
| "publish-packages": "pnpm build && changeset publish" | ||
| }, | ||
| "devDependencies": { | ||
| "@changesets/changelog-github": "^0.5.1", | ||
| "@changesets/cli": "^2.29.4", | ||
| "@codama/internals": "workspace:*", | ||
| "@eslint/js": "^9.26.0", | ||
| "@eslint/json": "^0.12.0", | ||
| "@solana/eslint-config-solana": "^4.0.0", | ||
| "@solana/prettier-config-solana": "0.0.5", | ||
| "@types/node": "^22", | ||
| "@typescript-eslint/eslint-plugin": "^8.32.1", | ||
| "@typescript-eslint/parser": "^8.32.0", | ||
| "agadoo": "^3.0.0", | ||
| "eslint": "^9.26.0", | ||
| "eslint-plugin-simple-import-sort": "^12.1.1", | ||
| "eslint-plugin-sort-keys-fix": "^1.1.2", | ||
| "eslint-plugin-typescript-sort-keys": "^3.3.0", | ||
| "happy-dom": "^17.4.7", | ||
| "prettier": "^3.5.3", | ||
| "rimraf": "6.0.1", | ||
| "turbo": "^2.5.3", | ||
| "tsup": "^8.4.0", | ||
| "typescript": "^5.8.3", | ||
| "vitest": "^3.1.3", | ||
| "zx": "^8.5.4" | ||
| }, | ||
| "engines": { | ||
| "node": ">=20.0.0" | ||
| }, | ||
| "packageManager": "[email protected]", | ||
| "prettier": "@solana/prettier-config-solana" | ||
| "name": "codama-monorepo", | ||
| "private": true, | ||
| "scripts": { | ||
| "build": "turbo run build --log-order grouped", | ||
| "lint": "turbo run lint --log-order grouped", | ||
| "lint:fix": "turbo lint:fix --log-order grouped && pnpm prettier --log-level warn --ignore-unknown --write '{.,!packages}/*'", | ||
| "test": "turbo run test --log-order grouped", | ||
| "publish-packages": "pnpm build && changeset publish" | ||
| }, | ||
| "devDependencies": { | ||
| "@changesets/changelog-github": "^0.5.1", | ||
| "@changesets/cli": "^2.29.5", | ||
| "@codama/internals": "workspace:*", | ||
| "@eslint/js": "^9.29.0", | ||
| "@eslint/json": "^0.12.0", | ||
| "@solana/eslint-config-solana": "^4.0.0", | ||
| "@solana/prettier-config-solana": "0.0.5", | ||
| "@types/node": "^24", | ||
| "@typescript-eslint/eslint-plugin": "^8.34.1", | ||
| "@typescript-eslint/parser": "^8.34.1", | ||
| "agadoo": "^3.0.0", | ||
| "eslint": "^9.29.0", | ||
| "eslint-plugin-simple-import-sort": "^12.1.1", | ||
| "eslint-plugin-sort-keys-fix": "^1.1.2", | ||
| "eslint-plugin-typescript-sort-keys": "^3.3.0", | ||
| "happy-dom": "^18.0.1", | ||
| "prettier": "^3.6.0", | ||
| "rimraf": "6.0.1", | ||
| "turbo": "^2.5.4", | ||
| "tsup": "^8.5.0", | ||
| "typescript": "^5.8.3", | ||
| "vitest": "^3.2.4", | ||
| "zx": "^8.5.5" | ||
| }, | ||
| "engines": { | ||
| "node": ">=20.0.0" | ||
| }, | ||
| "packageManager": "[email protected]", | ||
| "prettier": "@solana/prettier-config-solana" | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,206 @@ | ||
| # Codama ➤ Renderers ➤ Python | ||
|
|
||
| [![npm][npm-image]][npm-url] | ||
| [![npm-downloads][npm-downloads-image]][npm-url] | ||
|
|
||
| [npm-downloads-image]: https://img.shields.io/npm/dm/@codama/renderers-rust.svg?style=flat | ||
| [npm-image]: https://img.shields.io/npm/v/@codama/renderers-rust.svg?style=flat&label=%40codama%2Frenderers-rust | ||
| [npm-url]: https://www.npmjs.com/package/@codama/renderers-rust | ||
|
|
||
| This package generates Rust clients from your Codama IDLs. | ||
|
|
||
| ## Installation | ||
|
|
||
| ```sh | ||
| pnpm install @codama/renderers-py | ||
| ``` | ||
|
|
||
| > [!NOTE] | ||
| > This package is **not** included in the main [`codama`](../library) package. | ||
| > | ||
| > However, note that the [`renderers`](../renderers) package re-exports the `renderVisitor` function of this package as `renderPythonVisitor`. | ||
| ## Usage | ||
|
|
||
| Once you have a Codama IDL, you can use the `renderVisitor` of this package to generate Python clients. You will need to provide the base directory where the generated files will be saved and an optional set of options to customize the output. | ||
|
|
||
| ```ts | ||
| // node ./codama.mjs | ||
| import { renderVisitor } from '@codama/renderers-py'; | ||
|
|
||
| const pathToGeneratedFolder = path.join(__dirname, 'clients', 'python', 'src', 'generated'); | ||
| const options = {}; // See below. | ||
| codama.accept(renderVisitor(pathToGeneratedFolder, options)); | ||
| ``` | ||
|
|
||
| ## Generate file directory structure | ||
|
|
||
| ``` | ||
| . | ||
| ├── accounts | ||
| │ ├── foo_account.py | ||
| │ └── __init__.py | ||
| ├── instructions | ||
| │ ├── some_instruction.py | ||
| │ ├── other_instruction.py | ||
| │ └── __init__.py | ||
| ├── types | ||
| │ ├── bar_struct.py | ||
| │ ├── baz_enum.py | ||
| │ └── __init__.py | ||
| ├── errors | ||
| │ ├── custom.py | ||
| │ └── __init__.py | ||
| └── program_id.py | ||
| ``` | ||
|
|
||
| ## Dependencies | ||
|
|
||
| ``` | ||
| "borsh-construct>=0.1.0", | ||
| "anchorpy>=0.21.0", | ||
| "solana>=0.36.6", | ||
| "solders>=0.26.0", | ||
| ``` | ||
|
|
||
| ## Examples | ||
|
|
||
| ### Instructions | ||
|
|
||
| ```python | ||
| from solders.hash import Hash | ||
| from solders.keypair import Keypair | ||
| from solders.message import Message | ||
| from solders.pubkey import Pubkey | ||
| from solders.transaction import Transaction | ||
| from solana.rpc.async_api import AsyncClient | ||
| from my_client.instructions import some_instruction | ||
|
|
||
| # call an instruction | ||
| foo_account = Keypair() | ||
| async with AsyncClient("http://127.0.0.1:8899") as client: | ||
| res = await client.is_connected() | ||
| # in real use, fetch this from an RPC | ||
| recent_blockhash = (await client.get_latest_blockhash()).value.blockhash | ||
|
|
||
| ix = some_instruction({ | ||
| "foo_param": "...", | ||
| "bar_param": "...", | ||
| ... | ||
| }, | ||
| { | ||
| "foo_account": foo_account.pubkey(), # signer | ||
| "bar_account": Pubkey("..."), | ||
| ... | ||
| }) | ||
daog1 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| msg = Message(instructions=[ix], payer=payer.pubkey()) | ||
| try: | ||
| transaction = Transaction([foo_account], msg, recent_blockhash) | ||
| result = (await client.simulate_transaction(transaction)) | ||
| print(result) | ||
| except BaseException as e: | ||
| print(f"BaseException failed: {e}") | ||
| return None | ||
|
|
||
| ``` | ||
|
|
||
| ### Accounts | ||
|
|
||
| ```python | ||
| from solders.pubkey import Pubkey | ||
| from my_client.accounts import FooAccount | ||
|
|
||
| # fetch an account | ||
| addr = Pubkey("...") | ||
|
|
||
| acc = await FooAccount.fetch(connection, addr) | ||
| if acc is None: | ||
| # the fetch method returns null when the account is uninitialized | ||
| raise ValueError("account not found") | ||
|
|
||
|
|
||
| # convert to a JSON object | ||
| obj = acc.to_json() | ||
| print(obj) | ||
|
|
||
| # load from JSON | ||
| acc_from_json = FooAccount.from_json(obj) | ||
| ``` | ||
|
|
||
| ### Types | ||
|
|
||
| ```python | ||
| # structs | ||
|
|
||
| from my_client.types import BarStruct | ||
|
|
||
| bar_struct = BarStruct( | ||
| some_field="...", | ||
| other_field="...", | ||
| ) | ||
|
|
||
| print(bar_struct.to_json()) | ||
| ``` | ||
|
|
||
| ```python | ||
| # enums | ||
|
|
||
| from my_client.types import bazEnum | ||
|
|
||
| tupleEnum = bazEnum.SomeTupleKind((True, False, "some value")) | ||
| structEnum = bazEnum.SomeStructKind({ | ||
| "field1": "...", | ||
| "field2": "...", | ||
| }) | ||
| discEnum = bazEnum.SomeDiscriminantKind() | ||
|
|
||
| print(tupleEnum.toJSON(), structEnum.toJSON(), discEnum.toJSON()) | ||
| ``` | ||
|
|
||
| ```python | ||
| # types are used as arguments in instruction calls (where needed): | ||
| ix = some_instruction({ | ||
| "some_struct_field": bar_struct, | ||
| "some_enum_field": tuple_enum, | ||
| # ... | ||
| }, { | ||
| # accounts | ||
| # ... | ||
| }) | ||
|
|
||
| # in case of struct fields, it's also possible to pass them as objects: | ||
| ix = some_instruction({ | ||
| "some_struct_field": { | ||
| "some_field": "...", | ||
| "other_field": "...", | ||
| }, | ||
| # ..., | ||
| }, { | ||
| # accounts | ||
| # ... | ||
| }) | ||
| ``` | ||
|
|
||
| ### Errors | ||
|
|
||
| ```python | ||
| from solana.rpc.core import RPCException | ||
| from my_client.errors import from_tx_error | ||
| from my_client.errors.custom import SomeCustomError | ||
|
|
||
| try: | ||
| await provider.send(tx, [payer]) | ||
| except RPCException as exc: | ||
| parsed = from_tx_error(exc) | ||
| raise parsed from exc | ||
| ``` | ||
|
|
||
| ### Program ID | ||
|
|
||
| The Program ID is generated based on the Program address provided in the IDL. If it is not present in the IDL, it needs to be manually filled in. | ||
|
|
||
| ### Description | ||
|
|
||
| The generated code uses the AnchorPy code generation method and some underlying structures. | ||
|
|
||
| Support for Codama was added, and some data structures not supported by AnchorPy were included, such as FixedSizeType, SizePrefixType, HiddenSuffixType, HiddenPrefixType, and EnumIndexU32Type. | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.