{"id":25293566,"url":"https://github.com/convex-dev/tokengine","last_synced_at":"2026-07-26T10:32:32.451Z","repository":{"id":276951578,"uuid":"924082363","full_name":"Convex-Dev/tokengine","owner":"Convex-Dev","description":"Token exchange for lattice ecosystems","archived":false,"fork":false,"pushed_at":"2025-12-18T08:34:11.000Z","size":704,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"develop","last_synced_at":"2025-12-21T16:02:03.913Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Convex-Dev.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-01-29T11:38:44.000Z","updated_at":"2025-12-18T08:34:14.000Z","dependencies_parsed_at":"2025-03-07T12:23:35.522Z","dependency_job_id":"dac7596f-1fd5-4ad0-b49f-eadf3f6159b0","html_url":"https://github.com/Convex-Dev/tokengine","commit_stats":null,"previous_names":["convex-dev/tokengine"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Convex-Dev/tokengine","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Convex-Dev%2Ftokengine","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Convex-Dev%2Ftokengine/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Convex-Dev%2Ftokengine/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Convex-Dev%2Ftokengine/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Convex-Dev","download_url":"https://codeload.github.com/Convex-Dev/tokengine/tar.gz/refs/heads/develop","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Convex-Dev%2Ftokengine/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35911748,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-07-20T02:08:10.276Z","status":"online","status_checked_at":"2026-07-26T02:00:06.503Z","response_time":89,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-02-13T01:54:45.575Z","updated_at":"2026-07-26T10:32:32.441Z","avatar_url":"https://github.com/Convex-Dev.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# TokEngine\n\nTokEngine implements Cross-DLT Token exchange using Lattice Technology and [Convex](https://convex.world)\n\nThe official [TokEngine repository](https://github.com/Convex-Dev/tokengine) is hosted on GitHub\n\n## Fundamentals:  Atomic Exchange\n\nThe core of TokEngine is an atomic state machine that verifies incoming payments and produces outgoing transactions.\n\nKey features:\n- High performance asynchronous API server\n- Connectivity to multiple source DLTs\n- Use of CAIP standards to allow specification of token assets on any DLT \n- Supports any fungible tokens that can be transferred using verifiable DLT transactions\n- Verification of incoming payments on source DLTs, according to operator-defined security levels\n- Atomic update of user balance + record of incoming transaction. This gets logged (once) if successful\n- Atomic decrement of user balance for outgoing transaction\n\nTokEngine is designed to never create and store an inconsistent state, regardless of external failures. This is enforced by state transitions on a merkle tree lattice data structure.\n\n\n\n## CAIP Definitions\n\n#### Chain ID\n\nA [CAIP-2](https://chainagnostic.org/CAIPs/caip-2) Chain ID identifies a unique DLT network used by TokEngine\n\nExamples:\n\n- `convex:test` - Local Convex testnet\n- `eip155:11155111` - Ethereum Sepolia TestNet\n- `eip155:1` - Ethereum Mainnet\n\n#### Account ID\n\nA [CAIP-10](https://chainagnostic.org/CAIPs/caip-10) Account ID identifies a unique account on a DLT. It may be prefixed with the chain ID to specify which DLT the account is located on.\n\n- `eip155:1:0xab16a96D359eC26a11e2C2b3d8f8B8942d5Bfcdb` - Account on Ethereum Mainnet\n- `convex:main:56756` - Account `#56756` on Convex main network\n- `bip122:000000000019d6689c085ae165831e93:128Lkh3S7CkDTBZ8W7BbpsN3YYizJMp8p6` - Bitcoin account\n\n#### Asset Type\n\nA [CAIP-19](https://chainagnostic.org/CAIPs/caip-19) Asset Type identifies a token on a specific DLT\n\n- `eip155:1/slip44:60` - ETH on Ethereum Mainnet\n- `convex:main/slip44:864` - CVM on Convex main network\n- `eip155:11155111/erc20:0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238` - USDC ERC20 Stablecoin on Sepolia Testnet\n\nNote use of SLIP-44 to define native tokens\n\n## Example usage\n\nTypical usage of TokEngine is to make a deposit on one network (e.g. EVM), then pay out equivalent funds on a different network (e.g. CVM)\n\n### Basic Operator setup\n\n1. Download or build `tokengine.jar` ([snapshots available here](https://drive.google.com/drive/folders/1AZdyuZOmC70i_TtuEW3uEKvjYLOqIMiv))\n2. Place a config file in your home directory at `~/.tokengine/config.json`\n3. Run using Java 21+ with `java -jar tokengine.jar`\n\nThis should launch the TokEngine server. By default, a simple web interface and API definitions are available on [localhost:8080](http://localhost:8080)\n\n### Configure TokEngine\n\nYou will need to configure what networks tokens you want to support in `config.json`. This is a JSON5 formatted configuration file (this format allows comments, unlike regular JSON).\n\n#### Network\n\nSpecify a set of network adapters as follows:\n\n```json\n\t\"networks\" : [\n\t\t{\n\t\t\t\"description\": \"Convex main network (Protonet)\",\n\t\t\t\"alias\":\"convex\",                 // Short alias for network (Operator defined, must be unique in this config)\n\t\t \t\"chainID\":\"convex:main\",          // CAIP19 Chain ID\n\t\t\t\"url\":\"https://peer.convex.live\", // RPC / API endpoint\n\t\t\t\"receiverContract\":\"#14564\",\n\t\t\t\"operatorAddress\":\"#11\",\n\t\t\t\"timeout\": \"10000\" /* Millisecond timeout period */\n\t\t},{\n\t\t\t\"description\": \"Ethereum Sepolia test network\",\n\t\t\t\"alias\":\"sepolia\",\n\t\t \t\"chainID\":\"eip155:11155111\",\n\t\t\t\"url\":\"https://sepolia.drpc.org\",\n\t\t\t\"timeout\":\"300000\",\n\t\t\t\"receiverContract\":\"0xa752b195b4e7b1af82ca472756edfdb13bc9c79d\",\n\t\t\t\"operatorAddress\":\"0xa752b195b4e7b1af82ca472756edfdb13bc9c79d\"\n\t\t}\n\t}\n```\n\nRemember to set the following addresses (which you should control, i.e. securely hold the private keys):\n- `receiverAddress` to be the account address that TokEngine will use for received tokens\n- `operatorAddress` to be the account that will be user for TokEngine (unless an alternative treasury account is specified)\n\n#### Tokens\n\nSpecify the tokens you wish TokEngine to support as follows:\n\n```json\n\t\"tokens\" : [\n\t\t{\n\t\t\t\"alias\": \"CVM\", /* must match transfers category exactly */\n\t\t\t\"symbol\" : \"CVM\",\n\t\t\t\"name\" : \"Werecoin\"\n\t\t}\t\n\t\t{\n\t\t\t\"alias\": \"USDC\", /* must match transfers category exactly */\n\t\t\t\"symbol\" : \"USDC\",\n\t\t\t\"name\" : \"USDC Stablecoin\"\n\t\t}\n\t]\n```\n\nYou can give any name or symbol (these are primarily for display purposes). The alias is important as it uniquely identifies the token to TokEngine. It is recommended to use the most commonly recognised symbol as the alias (e.g. `BTC`, `CVM`, `USDT`)\n\n#### Transfers\n\nThe transfers section of the config defines which tokens are considered transferrable on which networks.\n\n```json\n  \"transfers\" : {\n\t \"CVM\": {\n\t\t\t\"convex\" : {\n\t\t\t\t\"symbol\":\"CVM\",\n\t\t\t\t\"assetID\":\"slip44:864\", /* This is native CVM */\n\t\t\t\t\"deposit\":true,\n\t\t\t\t\"payout\":true,\n\t\t\t\t\"isNative\":true   /* Optional, use this to signal a native coin for the network if required */\n\t\t\t},\n\t\t\t\"sepolia\": {\n\t\t\t\t\"symbol\":\"WCVM\",\n\t\t\t\t\"assetID\":\"erc20:0xff2eeb332708f9199d0c6e6f2e76286d79d9311e\", /* need to replace with correct WCVM token */\n\t\t\t\t\"treasuryID\":\"0xa752b195b4e7b1af82ca472756edfdb13bc9c79d\",\n\t\t\t\t\"deposit\":true,\n\t\t\t\t\"payout\":false\n\t\t\t}\n\t }\n\t ...\t\n  }\n```\n\nRules:\n\n- The aliases of the token and relevant network(s) must be used\n- Tokens MAY be assigned a different symbol on different networks. This is useful for wrapped versions of tokens, e.g. WCVM vs native CVM\n- The `assetID` must specify a valid CAIP-19 asset ID for the type of network. Typically `slip44` for native coins, `erc20` for EVM tokens and `cad29` for CVM tokens\n- Specify `deposit` and `payout` flags to enable/disable payouts for this particular token/network combination. The default is `true`\n- You may optionally specify a `treasuryID` which will be used for payouts on this network, which overrides the standard `operatorAddress`\n\n### Optional: Obtain tokens or deploy Contracts\n\nYou can deploy smart contracts to represent the tokens you wish to exchange. The method of doing so varies depending on specific network and token requirements and is outside the scope of TokEngine, however some examples are given for reference:\n\n- **ERC20 tokens on EVM networks** - A good example tutorial and code is available here: https://docs.openzeppelin.com/contracts/4.x/erc20\n- **CAD29 tokens on CVM networks** - Can be deployed in one line of code with a command like `(deploy (@convex.fungible/build-token {:supply 1000000}))` See also documentation at [docs.convex.world](https://docs.convex.world)\n\n\nFor an already existing token, refer to resources specific to that token. Test tokens are frequently available for free. Some examples are given below\n- **USDC** Available for free on testnets via https://faucet.circle.com/\n- **CVM** If you run your own CVM testnet you will be able to transfer test CVM from the genesis account\n- **ETH** Sepolia testnet faucet e.g. https://cloud.google.com/application/web3/faucet/ethereum/sepolia\n\n\n### API Example Flow\n\nBelow is an example of an end-to-end transfer use case using the API and a TokEngine instance set up as per the example above.\n\n#### Make a transfer to the TokeEngine receiver address \n\nThis can be done with any wallet.\n\ne.g. transaction `0x9d3a3663d32b9ff5cf2d393e433b7b31489d13b398133a35c4bb6e2085bd8e83` on Ethereum Sepolia transfers some USDC from `0xa72018ba06475aCa284ED98AB0cE0E07878521a3` to `0x5FbE74A283f7954f10AA04C2eDf55578811aeb03`\n\n(Here USDC is the contract address `0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238`\n\nThe destination address must be the receverAddress configured for that tokenm on TokEngine\n\n#### Register deposit\n\nCall the `deposit` endpoint to inform TokEngine of the deposit. The JSON payload should look like:\n\n```\n{\n  \"source\": {\n    \"account\": \"0xa72018ba06475aCa284ED98AB0cE0E07878521a3\",\n    \"network\": \"eip155:11155111\",\n    \"token\": \"erc20:0x1C7d4b196cb0c7b01d743fbc6116a902379c7238\"\n  },\n  \"deposit\": {\n    \"tx\": \"0x9d3a3663d32b9ff5cf2d393e433b7b31489d13b398133a35c4bb6e2085bd8e83\"\n  }\n}\n```\n\nTokEngine will check that:\n- The deposit has been made and signed correctly\n- The deposit transaction has not already been claimed, or is otherwise invalid\n\nIf successful, virtual credit will be given to the sender address\n\n#### Check balance\n\nVirtual credit with TokEngine can be checked with the `/api/v1/credit` endpoint. You can query the balance for an account on any registered network with a POST request like this:\n\n```\n{\n  \"source\": {\n    \"account\": \"0xa72018ba06475aCa284ED98AB0cE0E07878521a3\",\n    \"network\": \"sepolia\",\n    \"token\": \"erc20:0x1C7d4b196cb0c7b01d743fbc6116a902379c7238\"\n  }\n}\n```\n\nIf successful, using the configuration provided above, you should see a balance value returned in a response like:\n\n```\n{\n  \"value\": 6510\n}\n```\n\n\n### Payouts \n\nOnce virtual credit is available, a payout can be made to a target network, given proof of possession of the required private key\n\nThis is done by a request to the `api/v1/payout` endpoint, with a request structured like:\n\n```\n{\n  \"source\": {\n    \"account\": \"#11\",\n    \"network\": \"convex:test\",\n    \"token\": \"WCVM\"\n  },\n  \"destination\": {\n    \"account\": \"#13\",\n    \"network\": \"convex:test\",\n    \"token\": \"CVM\"\n  },\n  \"deposit\": {\n    \"tx\": \"0x9d3a3663d32b9ff5cf2d393e433b7b31489d13b398133a35c4bb6e2085bd8e83\",\n    \"msg\": \"Transfer 100000 to #13 on convex\",\n    \"sig\": \"0xdd48188b1647010d908e9fed4b6726cebd0d65e20f412b8b9ff4868386f05b0a28a9c0e35885c95e2322c2c670743edd07b0e1450ae65c3f6708b61bb3e582371c\"\n  },\n  \"quantity\": \"100000\"\n}\n```\n\nNote the `sig` field must be a correct signature of the `msg` for the address of the sender, to ensure only the authorised depositor is able to pay out their own virtual funds.\n\n\n\n## Overall design\n\n### Deposit\n\n0. User sends deposit on source DLT (client app)\n    - User sends tokens on source DLT to TokEngine operator receiver account\n    - User gets confirmed transaction ID (from source DLT)\n\n1. Validation (async)\n    - Validate API inputs for validity / correct format\n    - Validate that the asset specified is configured to receive deposits by the operator\n    - Validate that a deposit transaction has been correctly identified\n    - Log valid API request\n\n2. Verification stage (async)\n    - Verify transaction has been confirmed on source DLT\n    - If pending can wait for finality (optional)\n    - Verify transaction had triggered a deposit to the operator's receiver account\n\n3. Atomic update (sync)\n    - Check transaction has not already been atomically registered\n    - Perform atomic balance update\n    - Perform atomic registration of transaction as received\n    - Write state\n    - Create and write audit trail (if this fails, warning is logged but update is still safe)\n\n4. Confirmation (async)\n    - Return confirmation to API user\n\n### Withdraw\n\n1. Validation (async)\n    - Validate API inputs for validity / correct format\n    - Validate that the asset specified is configured to allow payouts by the operator\n    - Validate destination DLT address / specification\n    - Log valid API request\n\n2. Verification (async)\n    - Verify user has sufficient balance for payout (plus any fees)\n    - Verify signature on payout request\n    - Construct payout transaction (on dest DLT)\n\n3. Atomic prepare (sync)\n    - Record payout transaction (with ID for dest DLT)\n    - Lock payout amount from user\n    - Write state\n\n4. Transaction execution (async)\n    - Submit transaction to target DLT\n    - Return transaction ID to API caller\n    - Confirm completion of DLT payout transaction\n\n5. Atomic commit (sync, idempotent, can be retried)\n    - Check transaction not yet recorded as confirmed / failed\n    - Mark payout transaction as confirmed\n    - Decrement user balance (payout plus fees)\n    - Increment operator fee balance\n    - Write state\n    - Create and write audit trail (if this fails, warning is logged but update is still safe)\n\n6. Atomic rollback (sync, if transaction fails, idempotent, can be retired)\n    - Check transaction not yet recorded as confirmed / failed\n    - Record transaction as failed\n    - Decrement user balance (if any failure fees due)\n    - Increment operator fee balance (if any failure fees due)\n    - Unlock user funds\n    - Write state\n    - Create and write audit trail (if this fails, warning is logged but update is still safe)\n\n7. Confirmation (async polling by client app)\n    - Return confirmation / failure status to API user when polled\n\n### Transfer\n\nA transfer is a deposit plus withdraw flow in a single API call. All state updates are identical to a deposit+withdraw.\n\n## Tech notes\n\nThe design is intended to support high throughput concurrent usage:\n- Atomic sections are free of external interactions and generally run in-memory, completed in less than 1ms\n- All external operations are executed on lightweight virtual threads\n\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fconvex-dev%2Ftokengine","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fconvex-dev%2Ftokengine","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fconvex-dev%2Ftokengine/lists"}