├── docs ├── adhara │ ├── .gitignore │ ├── img │ │ ├── aspiration.png │ │ ├── interfaces.png │ │ ├── dvp_successful_trade.png │ │ ├── pvp_successful_trade.png │ │ ├── bank_side_generic_pattern.png │ │ ├── dvp_cancellation_on_corda.png │ │ ├── risks_as_platforms_scale.png │ │ ├── dvp_cancellation_on_ethereum.png │ │ ├── pvp_cancellation_on_leading.png │ │ └── pvp_cancellation_on_following.png │ ├── contents.md │ └── bank_side_patterns.md ├── r3 │ ├── witnesses.md │ ├── img │ │ └── atomic-dvp-sequence-diagram.jpeg │ ├── contents.md │ └── bounded_visibility.md └── fnality │ └── README.md ├── CODEOWNERS ├── src ├── adhara │ └── interop-service │ │ ├── .gitignore │ │ ├── besu │ │ └── services │ │ │ ├── node-1 │ │ │ └── data │ │ │ │ ├── DATABASE_METADATA.json │ │ │ │ ├── nodeAddress │ │ │ │ ├── key │ │ │ │ └── .gitignore │ │ │ ├── node-2 │ │ │ └── data │ │ │ │ ├── DATABASE_METADATA.json │ │ │ │ ├── nodeAddress │ │ │ │ ├── key │ │ │ │ └── .gitignore │ │ │ ├── stop.sh │ │ │ ├── cleanup-besu-db.sh │ │ │ ├── start.sh │ │ │ ├── server-check.sh │ │ │ ├── docker-compose-1.yaml │ │ │ ├── docker-compose-2.yaml │ │ │ ├── config.toml │ │ │ ├── genesis-1.json │ │ │ └── genesis-2.json │ │ ├── cordapp │ │ ├── gradle.properties │ │ ├── settings.gradle │ │ ├── clients │ │ │ ├── src │ │ │ │ └── main │ │ │ │ │ ├── resources │ │ │ │ │ ├── static │ │ │ │ │ │ ├── app.js │ │ │ │ │ │ └── index.html │ │ │ │ │ └── application.properties │ │ │ │ │ └── java │ │ │ │ │ └── net │ │ │ │ │ └── corda │ │ │ │ │ └── samples │ │ │ │ │ └── example │ │ │ │ │ └── webserver │ │ │ │ │ ├── requests │ │ │ │ │ ├── CancelXVPRequest.java │ │ │ │ │ ├── CreateDCRRequest.java │ │ │ │ │ ├── ResolveXVPRequest.java │ │ │ │ │ ├── EarmarkDCRRequest.java │ │ │ │ │ ├── CancelDCRRequest.java │ │ │ │ │ ├── CreateXVPRequest.java │ │ │ │ │ └── ConfirmDCRRequest.java │ │ │ │ │ ├── Properties.java │ │ │ │ │ ├── Starter.java │ │ │ │ │ └── NodeRPCConnection.java │ │ │ ├── Dockerfile │ │ │ └── Makefile │ │ ├── .gitignore │ │ ├── contracts │ │ │ ├── src │ │ │ │ ├── main │ │ │ │ │ └── java │ │ │ │ │ │ └── net │ │ │ │ │ │ └── corda │ │ │ │ │ │ └── samples │ │ │ │ │ │ └── example │ │ │ │ │ │ └── schema │ │ │ │ │ │ ├── DCRSchema.java │ │ │ │ │ │ └── XVPSchema.java │ │ │ │ └── test │ │ │ │ │ └── java │ │ │ │ │ └── net │ │ │ │ │ └── corda │ │ │ │ │ └── samples │ │ │ │ │ └── example │ │ │ │ │ └── contracts │ │ │ │ │ └── StateTests.java │ │ │ └── build.gradle │ │ ├── gradle │ │ │ └── wrapper │ │ │ │ ├── gradle-wrapper.jar │ │ │ │ └── gradle-wrapper.properties │ │ ├── README.md │ │ ├── TRADEMARK │ │ ├── entrypoint.sh │ │ ├── constants.properties │ │ ├── repositories.gradle │ │ ├── deploy │ │ │ └── corda-network │ │ │ │ ├── Chart.yaml │ │ │ │ ├── .helmignore │ │ │ │ └── templates │ │ │ │ └── configmap.yaml │ │ ├── Dockerfile │ │ ├── LICENCE │ │ ├── workflows │ │ │ └── src │ │ │ │ └── main │ │ │ │ └── resources │ │ │ │ └── migration │ │ │ │ ├── dcr.changelog-master.xml │ │ │ │ ├── xvp.changelog-master.xml │ │ │ │ ├── xvp.changelog-v1.xml │ │ │ │ └── dcr.changelog-v1.xml │ │ ├── config │ │ │ └── test │ │ │ │ └── log4j2.xml │ │ └── Makefile │ │ ├── corda-decoder │ │ ├── .gitignore │ │ ├── src │ │ │ ├── main │ │ │ │ ├── java │ │ │ │ │ └── io │ │ │ │ │ │ └── adhara │ │ │ │ │ │ └── poc │ │ │ │ │ │ ├── amqp │ │ │ │ │ │ ├── types │ │ │ │ │ │ │ ├── DescribedType.java │ │ │ │ │ │ │ ├── UnknownDescribedType.java │ │ │ │ │ │ │ ├── Decimal32.java │ │ │ │ │ │ │ └── Decimal64.java │ │ │ │ │ │ └── codec │ │ │ │ │ │ │ ├── DescribedTypeConstructor.java │ │ │ │ │ │ │ ├── ByteBufferEncoder.java │ │ │ │ │ │ │ ├── TypeConstructor.java │ │ │ │ │ │ │ ├── ByteBufferDecoder.java │ │ │ │ │ │ │ ├── Codec.java │ │ │ │ │ │ │ ├── PrimitiveTypeEncoding.java │ │ │ │ │ │ │ ├── AbstractPrimitiveType.java │ │ │ │ │ │ │ ├── AMQPType.java │ │ │ │ │ │ │ ├── PrimitiveType.java │ │ │ │ │ │ │ ├── AMQPDefinedTypes.java │ │ │ │ │ │ │ ├── TypeEncoding.java │ │ │ │ │ │ │ ├── DecodeException.java │ │ │ │ │ │ │ ├── EncodeException.java │ │ │ │ │ │ │ ├── FastPathDescribedTypeConstructor.java │ │ │ │ │ │ │ ├── LargeFloatingSizePrimitiveTypeEncoding.java │ │ │ │ │ │ │ ├── SmallFloatingSizePrimitiveTypeEncoding.java │ │ │ │ │ │ │ ├── FixedSizePrimitiveTypeEncoding.java │ │ │ │ │ │ │ ├── NullElement.java │ │ │ │ │ │ │ ├── Element.java │ │ │ │ │ │ │ ├── CharElement.java │ │ │ │ │ │ │ ├── FloatingSizePrimitiveTypeEncoding.java │ │ │ │ │ │ │ ├── FloatElement.java │ │ │ │ │ │ │ ├── DoubleElement.java │ │ │ │ │ │ │ ├── TimestampElement.java │ │ │ │ │ │ │ ├── ByteElement.java │ │ │ │ │ │ │ ├── ShortElement.java │ │ │ │ │ │ │ ├── AbstractPrimitiveTypeEncoding.java │ │ │ │ │ │ │ ├── Decimal32Element.java │ │ │ │ │ │ │ ├── Decimal64Element.java │ │ │ │ │ │ │ ├── UUIDElement.java │ │ │ │ │ │ │ ├── AtomicElement.java │ │ │ │ │ │ │ ├── BooleanElement.java │ │ │ │ │ │ │ ├── Decimal128Element.java │ │ │ │ │ │ │ ├── UnsignedByteElement.java │ │ │ │ │ │ │ ├── UnsignedShortElement.java │ │ │ │ │ │ │ ├── DynamicTypeConstructor.java │ │ │ │ │ │ │ ├── LongElement.java │ │ │ │ │ │ │ ├── IntegerElement.java │ │ │ │ │ │ │ ├── DescribedTypeImpl.java │ │ │ │ │ │ │ ├── DroppingWritableBuffer.java │ │ │ │ │ │ │ ├── NullType.java │ │ │ │ │ │ │ ├── Decimal32Type.java │ │ │ │ │ │ │ ├── Decimal64Type.java │ │ │ │ │ │ │ ├── UnsignedLongElement.java │ │ │ │ │ │ │ ├── UnsignedIntegerElement.java │ │ │ │ │ │ │ └── SymbolElement.java │ │ │ │ │ │ ├── ledger │ │ │ │ │ │ ├── SignedMeta.java │ │ │ │ │ │ ├── PartialPair.java │ │ │ │ │ │ ├── SignableData.java │ │ │ │ │ │ ├── ComponentGroup.java │ │ │ │ │ │ ├── MerkleProof.java │ │ │ │ │ │ ├── Extracted.java │ │ │ │ │ │ ├── PartialTree.java │ │ │ │ │ │ └── SignedData.java │ │ │ │ │ │ └── rest │ │ │ │ │ │ ├── DecoderService.java │ │ │ │ │ │ ├── model │ │ │ │ │ │ └── LedgerTransaction.java │ │ │ │ │ │ └── controller │ │ │ │ │ │ └── DecodeAndVerifyTransactionController.java │ │ │ │ └── resources │ │ │ │ │ └── application.properties │ │ │ └── test │ │ │ │ └── java │ │ │ │ └── io.adhara.poc │ │ │ │ └── rest │ │ │ │ └── DecoderServiceTests.java │ │ ├── Dockerfile │ │ └── Makefile │ │ └── crosschainInterop │ │ ├── .dockerignore │ │ ├── src │ │ ├── CrosschainApplicationSDK │ │ │ ├── validatorSetInstructionStates.js │ │ │ ├── validatorUpdateInstructionStates.js │ │ │ ├── settlementInstructionStates.js │ │ │ ├── repoObligations.js │ │ │ ├── helpers.js │ │ │ └── validatorSetManager.js │ │ ├── CrosschainSDKUtils │ │ │ ├── errors.js │ │ │ └── logger.js │ │ └── Adapters │ │ │ └── EthClient │ │ │ └── settlementObligations.js │ │ ├── api │ │ ├── package.json │ │ ├── app │ │ │ ├── services │ │ │ │ ├── repoObligationService.js │ │ │ │ ├── settlementObligationService.js │ │ │ │ └── settlementInstructionService.js │ │ │ └── paths │ │ │ │ └── {networkId} │ │ │ │ ├── repoObligations.js │ │ │ │ └── settlementObligations.js │ │ ├── admin │ │ │ ├── services │ │ │ │ ├── validatorService.js │ │ │ │ ├── cordaNotaryService.js │ │ │ │ ├── cordaParticipantService.js │ │ │ │ ├── validatorSetService.js │ │ │ │ ├── validatorUpdateService.js │ │ │ │ ├── interopAuthParamService.js │ │ │ │ ├── interopParticipantService.js │ │ │ │ └── cordaRegisteredFunctionService.js │ │ │ └── paths │ │ │ │ └── validators.js │ │ └── README.md │ │ ├── .gitignore │ │ ├── contracts │ │ ├── test │ │ │ ├── Base64Verify.sol │ │ │ ├── X509Verify.sol │ │ │ ├── SECP256K1Verify.sol │ │ │ ├── ED25519Verify.sol │ │ │ ├── SECP256R1Verify.sol │ │ │ ├── MerkleVerify.sol │ │ │ └── EthereumVerify.sol │ │ ├── interfaces │ │ │ ├── IFeeManager.sol │ │ │ └── ICrosschainVerifier.sol │ │ └── AuthParams.sol │ │ ├── Dockerfile │ │ ├── Makefile │ │ └── test │ │ └── base64Verify.js └── r3 │ └── atomic-swap │ ├── evm │ ├── settings.gradle │ ├── remappings.txt │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── foundry.toml │ ├── package.json │ ├── .gitignore │ ├── entrypoint.sh │ ├── .github │ │ └── workflows │ │ │ └── test.yml │ ├── Dockerfile │ ├── hardhat.config.js │ ├── script │ │ └── SwapVault.s.sol │ ├── build.gradle │ ├── deploy.js │ └── src │ │ └── TestToken.sol │ └── corda │ ├── .idea │ └── .gitignore │ ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties │ ├── settings.gradle │ ├── gradle.properties │ ├── evm-interop-workflows │ └── src │ │ └── main │ │ └── kotlin │ │ └── com │ │ └── r3 │ │ └── corda │ │ └── evminterop │ │ ├── services │ │ ├── IEther.kt │ │ ├── IBridge.kt │ │ ├── internal │ │ │ └── RemoteEVMIdentityImpl.kt │ │ ├── ConnectionId.kt │ │ ├── IERC20.kt │ │ ├── BridgeIdentityWithSigner.kt │ │ ├── ResponseOperation.kt │ │ ├── RemoteEVMIdentity.kt │ │ ├── AuthorizedSigner.kt │ │ └── IWeb3.kt │ │ └── workflows │ │ ├── swap │ │ ├── CommitmentHash.kt │ │ ├── RevertCommitment.kt │ │ ├── ClaimCommitment.kt │ │ └── RequestNotarisationProofsInitiator.kt │ │ ├── UnsecureRemoteEvmIdentityFlow.kt │ │ ├── eth2eth │ │ ├── GetTransactionFlow.kt │ │ ├── Erc20TokensTotalSupplyFlow.kt │ │ ├── GetTransactionReceiptFlow.kt │ │ └── Erc20TokensBalanceFlow.kt │ │ └── internal │ │ └── Utils.kt │ ├── constants.properties │ ├── repositories.gradle │ ├── evm-interop-contracts │ ├── src │ │ └── main │ │ │ └── kotlin │ │ │ └── com │ │ │ └── r3 │ │ │ └── corda │ │ │ └── evminterop │ │ │ ├── dto │ │ │ ├── ContractInfo.kt │ │ │ ├── TokenMetadata.kt │ │ │ ├── TokenSetup.kt │ │ │ ├── TokenMetadataWithBalance.kt │ │ │ ├── Transaction.kt │ │ │ ├── Block.kt │ │ │ └── DepositStates.kt │ │ │ └── states │ │ │ └── swap │ │ │ ├── UnlockData.kt │ │ │ ├── LockState.kt │ │ │ └── SwapTransactionDetails.kt │ └── build.gradle │ ├── samples │ └── atomic-swap │ │ └── swap-workflows │ │ └── src │ │ └── main │ │ └── kotlin │ │ └── com │ │ └── interop │ │ └── flows │ │ └── SignDraftTransactionByIDFlow.kt │ ├── evm-interop-common │ ├── src │ │ └── main │ │ │ └── kotlin │ │ │ └── com │ │ │ └── r3 │ │ │ └── corda │ │ │ └── interop │ │ │ └── evm │ │ │ └── common │ │ │ └── trie │ │ │ ├── EmptyNode.kt │ │ │ └── KeyValueStore.kt │ └── build.gradle │ └── .gitignore ├── .gitignore ├── .gitmodules └── .github ├── settings.yml └── workflows └── gradle.yml /docs/adhara/.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | -------------------------------------------------------------------------------- /docs/r3/witnesses.md: -------------------------------------------------------------------------------- 1 | # Witnesses 2 | -------------------------------------------------------------------------------- /CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @hyperledger-labs/harmonia-committers 2 | -------------------------------------------------------------------------------- /src/adhara/interop-service/.gitignore: -------------------------------------------------------------------------------- 1 | .gradle/ 2 | .idea/ 3 | .vscode/ 4 | *.swp 5 | -------------------------------------------------------------------------------- /src/adhara/interop-service/besu/services/node-1/data/DATABASE_METADATA.json: -------------------------------------------------------------------------------- 1 | {"version":1} -------------------------------------------------------------------------------- /src/adhara/interop-service/besu/services/node-2/data/DATABASE_METADATA.json: -------------------------------------------------------------------------------- 1 | {"version":1} -------------------------------------------------------------------------------- /src/r3/atomic-swap/evm/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'sample-project-gradle' 2 | 3 | -------------------------------------------------------------------------------- /src/r3/atomic-swap/corda/.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | -------------------------------------------------------------------------------- /src/adhara/interop-service/besu/services/node-1/data/nodeAddress: -------------------------------------------------------------------------------- 1 | 0xca31306798b41bc81c43094a1e0462890ce7a673 -------------------------------------------------------------------------------- /src/adhara/interop-service/besu/services/node-2/data/nodeAddress: -------------------------------------------------------------------------------- 1 | 0xca31306798b41bc81c43094a1e0462890ce7a673 -------------------------------------------------------------------------------- /src/adhara/interop-service/cordapp/gradle.properties: -------------------------------------------------------------------------------- 1 | name=Example Cordapp 2 | group=com.example 3 | version=0.1 -------------------------------------------------------------------------------- /src/adhara/interop-service/cordapp/settings.gradle: -------------------------------------------------------------------------------- 1 | include 'workflows' 2 | include 'contracts' 3 | include 'clients' -------------------------------------------------------------------------------- /docs/adhara/img/aspiration.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hyperledger-labs/harmonia/HEAD/docs/adhara/img/aspiration.png -------------------------------------------------------------------------------- /docs/adhara/img/interfaces.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hyperledger-labs/harmonia/HEAD/docs/adhara/img/interfaces.png -------------------------------------------------------------------------------- /src/adhara/interop-service/besu/services/node-1/data/key: -------------------------------------------------------------------------------- 1 | 0x0315c9adce270b738b7325fae9e03f2c1a7179813f8d06355fbec6d4996af114 -------------------------------------------------------------------------------- /src/adhara/interop-service/besu/services/node-2/data/key: -------------------------------------------------------------------------------- 1 | 0x0315c9adce270b738b7325fae9e03f2c1a7179813f8d06355fbec6d4996af114 -------------------------------------------------------------------------------- /src/adhara/interop-service/corda-decoder/.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | .vscode/ 3 | .gradle/ 4 | 5 | target/ 6 | bin/ 7 | build/ 8 | logs/ 9 | -------------------------------------------------------------------------------- /src/adhara/interop-service/cordapp/clients/src/main/resources/static/app.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | // Define your client-side logic here. -------------------------------------------------------------------------------- /docs/adhara/img/dvp_successful_trade.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hyperledger-labs/harmonia/HEAD/docs/adhara/img/dvp_successful_trade.png -------------------------------------------------------------------------------- /docs/adhara/img/pvp_successful_trade.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hyperledger-labs/harmonia/HEAD/docs/adhara/img/pvp_successful_trade.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # General macOS and Windows files 2 | .DS_Store 3 | .AppleDouble 4 | .LSOverride 5 | Icon 6 | Thumbs.db 7 | Thumbs.db:encryptable 8 | -------------------------------------------------------------------------------- /docs/adhara/img/bank_side_generic_pattern.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hyperledger-labs/harmonia/HEAD/docs/adhara/img/bank_side_generic_pattern.png -------------------------------------------------------------------------------- /docs/adhara/img/dvp_cancellation_on_corda.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hyperledger-labs/harmonia/HEAD/docs/adhara/img/dvp_cancellation_on_corda.png -------------------------------------------------------------------------------- /docs/adhara/img/risks_as_platforms_scale.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hyperledger-labs/harmonia/HEAD/docs/adhara/img/risks_as_platforms_scale.png -------------------------------------------------------------------------------- /docs/r3/img/atomic-dvp-sequence-diagram.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hyperledger-labs/harmonia/HEAD/docs/r3/img/atomic-dvp-sequence-diagram.jpeg -------------------------------------------------------------------------------- /docs/adhara/img/dvp_cancellation_on_ethereum.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hyperledger-labs/harmonia/HEAD/docs/adhara/img/dvp_cancellation_on_ethereum.png -------------------------------------------------------------------------------- /docs/adhara/img/pvp_cancellation_on_leading.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hyperledger-labs/harmonia/HEAD/docs/adhara/img/pvp_cancellation_on_leading.png -------------------------------------------------------------------------------- /src/adhara/interop-service/besu/services/stop.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | docker-compose -f docker-compose-1.yaml -f docker-compose-2.yaml down -v 4 | -------------------------------------------------------------------------------- /src/adhara/interop-service/cordapp/.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | .vscode/ 3 | .gradle/ 4 | 5 | target/ 6 | bin/ 7 | build/ 8 | logs/ 9 | 10 | *.log 11 | -------------------------------------------------------------------------------- /docs/adhara/img/pvp_cancellation_on_following.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hyperledger-labs/harmonia/HEAD/docs/adhara/img/pvp_cancellation_on_following.png -------------------------------------------------------------------------------- /src/adhara/interop-service/besu/services/node-1/data/.gitignore: -------------------------------------------------------------------------------- 1 | # Local pantheon database 2 | database 3 | uploads 4 | caches 5 | besu.networks 6 | besu.ports 7 | -------------------------------------------------------------------------------- /src/adhara/interop-service/besu/services/node-2/data/.gitignore: -------------------------------------------------------------------------------- 1 | # Local pantheon database 2 | database 3 | upload 4 | caches 5 | besu.networks 6 | besu.ports 7 | -------------------------------------------------------------------------------- /src/adhara/interop-service/cordapp/clients/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | config=/home/coenie/workspace/adhara-labs/crosschainInterop/config/config.json 2 | -------------------------------------------------------------------------------- /src/r3/atomic-swap/evm/remappings.txt: -------------------------------------------------------------------------------- 1 | ds-test/=lib/forge-std/lib/ds-test/src/ 2 | forge-std/=lib/forge-std/src/ 3 | openzeppelin/=lib/openzeppelin-contracts/contracts/ -------------------------------------------------------------------------------- /src/adhara/interop-service/crosschainInterop/.dockerignore: -------------------------------------------------------------------------------- 1 | # This will prevent files that are not needed in the docker image 2 | 3 | /docs* 4 | /migrations* 5 | /test* 6 | -------------------------------------------------------------------------------- /src/r3/atomic-swap/evm/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hyperledger-labs/harmonia/HEAD/src/r3/atomic-swap/evm/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /src/r3/atomic-swap/corda/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hyperledger-labs/harmonia/HEAD/src/r3/atomic-swap/corda/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /src/adhara/interop-service/cordapp/contracts/src/main/java/net/corda/samples/example/schema/DCRSchema.java: -------------------------------------------------------------------------------- 1 | package net.corda.samples.example.schema; 2 | 3 | public class DCRSchema { } -------------------------------------------------------------------------------- /src/adhara/interop-service/cordapp/contracts/src/main/java/net/corda/samples/example/schema/XVPSchema.java: -------------------------------------------------------------------------------- 1 | package net.corda.samples.example.schema; 2 | 3 | public class XVPSchema { } -------------------------------------------------------------------------------- /src/r3/atomic-swap/corda/settings.gradle: -------------------------------------------------------------------------------- 1 | include 'evm-interop-common' 2 | include 'evm-interop-contracts' 3 | include 'evm-interop-workflows' 4 | include 'samples:atomic-swap:swap-workflows' -------------------------------------------------------------------------------- /src/adhara/interop-service/cordapp/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hyperledger-labs/harmonia/HEAD/src/adhara/interop-service/cordapp/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /src/r3/atomic-swap/evm/foundry.toml: -------------------------------------------------------------------------------- 1 | [profile.default] 2 | src = 'src' 3 | out = 'out' 4 | libs = ['lib'] 5 | 6 | # See more config options https://github.com/foundry-rs/foundry/tree/master/config -------------------------------------------------------------------------------- /src/adhara/interop-service/besu/services/cleanup-besu-db.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | rm -rf node-1/data/database 3 | rm -rf node-1/data/caches 4 | rm -rf node-2/data/database 5 | rm -rf node-2/data/caches 6 | 7 | -------------------------------------------------------------------------------- /src/adhara/interop-service/cordapp/clients/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine:3.17.3 2 | 3 | RUN apk add openjdk8-jre 4 | 5 | WORKDIR /clients 6 | 7 | COPY /build/libs/ /clients 8 | 9 | ENTRYPOINT [ "java", "-jar", "clients-0.1.jar" ] -------------------------------------------------------------------------------- /src/r3/atomic-swap/corda/gradle.properties: -------------------------------------------------------------------------------- 1 | #name=Test 2 | #group=com.template 3 | version=0.1 4 | kotlin.incremental=false 5 | web3jVersion=4.12.1 6 | mockitoVersion=2.28.2 7 | org.gradle.jvmargs=--add-opens java.base/java.time=ALL-UNNAMED 8 | -------------------------------------------------------------------------------- /src/adhara/interop-service/corda-decoder/src/main/java/io/adhara/poc/amqp/types/DescribedType.java: -------------------------------------------------------------------------------- 1 | package io.adhara.poc.amqp.types; 2 | 3 | public interface DescribedType { 4 | Object getDescriptor(); 5 | 6 | Object getDescribed(); 7 | } 8 | -------------------------------------------------------------------------------- /src/adhara/interop-service/besu/services/start.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | docker-compose -f docker-compose-1.yaml -f docker-compose-2.yaml up -d 4 | 5 | docker-compose -f docker-compose-1.yaml -f docker-compose-2.yaml logs --tail=0 --follow 6 | -------------------------------------------------------------------------------- /src/adhara/interop-service/cordapp/README.md: -------------------------------------------------------------------------------- 1 | # cordapp-example 2 | 3 | This repo is the implementation of the tutorial cordapp. 4 | 5 | You can find that tutorial here: 6 | 7 | https://docs.corda.net/docs/corda-os/4.7/tutorial-cordapp.html 8 | -------------------------------------------------------------------------------- /src/r3/atomic-swap/evm/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "@nomicfoundation/hardhat-foundry": "^1.1.1", 4 | "@nomiclabs/hardhat-waffle": "^2.0.3", 5 | "@openzeppelin/contracts": "^4.8.0", 6 | "hardhat": "^2.12.2" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/adhara/interop-service/corda-decoder/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.application.name=corda-decoder 2 | server.port=8080 3 | logging.level.org.springframework=DEBUG 4 | logging.level.root=DEBUG 5 | logging.level.org.springframework.data=DEBUG 6 | -------------------------------------------------------------------------------- /docs/fnality/README.md: -------------------------------------------------------------------------------- 1 | # Fnality docs 2 | 3 | Documents provided by Fnality: 4 | * **Regulated Systems Requirements**: document outlining the Requirements and Assumptions for interoperability between regulated systems, such as Payment Systems and Securities Settlement Systems. 5 | -------------------------------------------------------------------------------- /src/adhara/interop-service/corda-decoder/src/main/java/io/adhara/poc/amqp/codec/DescribedTypeConstructor.java: -------------------------------------------------------------------------------- 1 | package io.adhara.poc.amqp.codec; 2 | 3 | public interface DescribedTypeConstructor { 4 | V newInstance(Object described); 5 | 6 | Class getTypeClass(); 7 | } 8 | -------------------------------------------------------------------------------- /src/r3/atomic-swap/evm/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /src/adhara/interop-service/corda-decoder/src/main/java/io/adhara/poc/amqp/codec/ByteBufferEncoder.java: -------------------------------------------------------------------------------- 1 | package io.adhara.poc.amqp.codec; 2 | 3 | import java.nio.ByteBuffer; 4 | 5 | public interface ByteBufferEncoder extends Encoder { 6 | void setByteBuffer(ByteBuffer buf); 7 | } 8 | -------------------------------------------------------------------------------- /src/adhara/interop-service/cordapp/TRADEMARK: -------------------------------------------------------------------------------- 1 | Corda and the Corda logo are trademarks of R3CEV LLC and its affiliates. All rights reserved. 2 | 3 | For R3CEV LLC's trademark and logo usage information, please consult our Trademark Usage Policy at 4 | https://www.r3.com/trademark-policy/. -------------------------------------------------------------------------------- /src/adhara/interop-service/cordapp/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "Running DB migration" 4 | 5 | java -jar /opt/corda/bin/corda.jar run-migration-scripts --core-schemas --app-schemas --allow-hibernate-to-manage-app-schema 6 | 7 | 8 | echo "Starting corda node" 9 | run-corda 10 | -------------------------------------------------------------------------------- /src/adhara/interop-service/crosschainInterop/src/CrosschainApplicationSDK/validatorSetInstructionStates.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | confirmed: 'confirmed', 3 | waitingForCrosschainFunctionCall: 'waitingForCrosschainFunctionCall', 4 | processed: 'processed', 5 | failed: 'failed', 6 | timedOut: 'timedOut', 7 | } 8 | -------------------------------------------------------------------------------- /src/r3/atomic-swap/corda/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Aug 25 12:50:39 BST 2017 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip 5 | zipStoreBase=GRADLE_USER_HOME 6 | zipStorePath=wrapper/dists 7 | -------------------------------------------------------------------------------- /src/adhara/interop-service/corda-decoder/src/main/java/io/adhara/poc/amqp/codec/TypeConstructor.java: -------------------------------------------------------------------------------- 1 | package io.adhara.poc.amqp.codec; 2 | 3 | public interface TypeConstructor { 4 | V readValue(); 5 | 6 | void skipValue(); 7 | 8 | boolean encodesJavaPrimitive(); 9 | 10 | Class getTypeClass(); 11 | } 12 | -------------------------------------------------------------------------------- /src/adhara/interop-service/crosschainInterop/src/CrosschainApplicationSDK/validatorUpdateInstructionStates.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | confirmed: 'confirmed', 3 | waitingForCrosschainFunctionCall: 'waitingForCrosschainFunctionCall', 4 | processed: 'processed', 5 | failed: 'failed', 6 | timedOut: 'timedOut', 7 | } 8 | -------------------------------------------------------------------------------- /src/adhara/interop-service/besu/services/server-check.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getBlockByNumber","params":["latest", false],"id":1}' localhost:8545 4 | #curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getBlockByNumber","params":["latest", false],"id":1}' localhost:7545 5 | -------------------------------------------------------------------------------- /src/adhara/interop-service/cordapp/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Aug 25 12:50:39 BST 2017 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip 7 | 8 | -------------------------------------------------------------------------------- /src/adhara/interop-service/corda-decoder/src/main/java/io/adhara/poc/amqp/codec/ByteBufferDecoder.java: -------------------------------------------------------------------------------- 1 | package io.adhara.poc.amqp.codec; 2 | 3 | import java.nio.ByteBuffer; 4 | 5 | public interface ByteBufferDecoder extends Decoder { 6 | void setByteBuffer(ByteBuffer buffer); 7 | 8 | int getByteBufferRemaining(); 9 | } 10 | -------------------------------------------------------------------------------- /src/r3/atomic-swap/corda/evm-interop-workflows/src/main/kotlin/com/r3/corda/evminterop/services/IEther.kt: -------------------------------------------------------------------------------- 1 | package com.r3.corda.evminterop.services 2 | 3 | import net.corda.core.flows.FlowExternalOperation 4 | import java.math.BigInteger 5 | 6 | interface IEther { 7 | fun balanceOf(address: String): FlowExternalOperation 8 | } -------------------------------------------------------------------------------- /src/adhara/interop-service/corda-decoder/src/main/java/io/adhara/poc/amqp/codec/Codec.java: -------------------------------------------------------------------------------- 1 | package io.adhara.poc.amqp.codec; 2 | 3 | /** 4 | * Codec 5 | */ 6 | 7 | public final class Codec { 8 | 9 | private Codec() { 10 | } 11 | 12 | public static Data data(long capacity) { 13 | return Data.Factory.create(); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "src/r3/atomic-swap/evm/lib/forge-std"] 2 | path = src/r3/atomic-swap/evm/lib/forge-std 3 | url = https://github.com/foundry-rs/forge-std 4 | [submodule "src/r3/atomic-swap/evm/lib/openzeppelin-contracts"] 5 | path = src/r3/atomic-swap/evm/lib/openzeppelin-contracts 6 | url = https://github.com/OpenZeppelin/openzeppelin-contracts 7 | -------------------------------------------------------------------------------- /src/adhara/interop-service/corda-decoder/src/main/java/io/adhara/poc/ledger/SignedMeta.java: -------------------------------------------------------------------------------- 1 | package io.adhara.poc.ledger; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | @Data 8 | @AllArgsConstructor 9 | public class SignedMeta { 10 | private Integer platformVersion; 11 | private Integer schemaNumber; 12 | } 13 | -------------------------------------------------------------------------------- /.github/settings.yml: -------------------------------------------------------------------------------- 1 | # 2 | # SPDX-License-Identifier: Apache-2.0 3 | # 4 | 5 | repository: 6 | name: harmonia 7 | default_branch: main 8 | has_downloads: false 9 | has_issues: true 10 | has_projects: false 11 | has_wiki: true 12 | archived: false 13 | private: false 14 | allow_squash_merge: true 15 | allow_merge_commit: false 16 | allow_rebase_merge: true 17 | -------------------------------------------------------------------------------- /src/adhara/interop-service/corda-decoder/src/main/java/io/adhara/poc/amqp/codec/PrimitiveTypeEncoding.java: -------------------------------------------------------------------------------- 1 | package io.adhara.poc.amqp.codec; 2 | 3 | public interface PrimitiveTypeEncoding extends TypeEncoding, TypeConstructor { 4 | PrimitiveType getType(); 5 | 6 | byte getEncodingCode(); 7 | 8 | void writeConstructor(); 9 | 10 | int getConstructorSize(); 11 | } 12 | -------------------------------------------------------------------------------- /src/adhara/interop-service/corda-decoder/src/main/java/io/adhara/poc/ledger/PartialPair.java: -------------------------------------------------------------------------------- 1 | package io.adhara.poc.ledger; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | @Data 8 | @AllArgsConstructor 9 | @NoArgsConstructor 10 | public class PartialPair { 11 | private Boolean hasIncludedLeaf; 12 | private PartialTree tree; 13 | } 14 | -------------------------------------------------------------------------------- /src/adhara/interop-service/corda-decoder/src/main/java/io/adhara/poc/amqp/codec/AbstractPrimitiveType.java: -------------------------------------------------------------------------------- 1 | package io.adhara.poc.amqp.codec; 2 | 3 | abstract class AbstractPrimitiveType implements PrimitiveType { 4 | public final void write(T val) { 5 | final TypeEncoding encoding = getEncoding(val); 6 | encoding.writeConstructor(); 7 | encoding.writeValue(val); 8 | } 9 | 10 | } 11 | -------------------------------------------------------------------------------- /src/adhara/interop-service/cordapp/clients/src/main/java/net/corda/samples/example/webserver/requests/CancelXVPRequest.java: -------------------------------------------------------------------------------- 1 | package net.corda.samples.example.webserver.requests; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | @Data 8 | @AllArgsConstructor 9 | @NoArgsConstructor 10 | public class CancelXVPRequest { 11 | private String tradeId; 12 | } 13 | -------------------------------------------------------------------------------- /src/r3/atomic-swap/corda/constants.properties: -------------------------------------------------------------------------------- 1 | cordaReleaseGroup=net.corda 2 | cordaCoreReleaseGroup=net.corda 3 | cordaVersion=4.12 4 | cordaCoreVersion=4.12 5 | gradlePluginsVersion=5.1.1 6 | kotlinVersion=1.9.20 7 | junitVersion=5.9.0 8 | #try this out 9 | quasarVersion=0.9.0_r3 10 | log4jVersion=2.23.1 11 | platformVersion=140 12 | persistenceVersion=2.2 13 | slf4jVersion=2.0.12 14 | nettyVersion=4.1.77.Final 15 | 16 | -------------------------------------------------------------------------------- /src/adhara/interop-service/cordapp/constants.properties: -------------------------------------------------------------------------------- 1 | cordaReleaseGroup=net.corda 2 | cordaCoreReleaseGroup=net.corda 3 | cordaVersion=4.12 4 | cordaCoreVersion=4.12 5 | gradlePluginsVersion=5.1.1 6 | kotlinVersion=1.9.20 7 | junitVersion=4.12 8 | quasarVersion=0.9.0_r3 9 | log4jVersion =2.17.1 10 | platformVersion=6 11 | slf4jVersion=1.7.25 12 | nettyVersion=4.1.22.Final 13 | persistenceVersion=2.2 14 | annotationVersion=2.1.0 -------------------------------------------------------------------------------- /src/r3/atomic-swap/corda/repositories.gradle: -------------------------------------------------------------------------------- 1 | repositories { 2 | mavenLocal() 3 | mavenCentral() 4 | maven { url 'https://jitpack.io' } 5 | maven { url 'https://download.corda.net/maven/corda' } 6 | maven { url 'https://download.corda.net/maven/corda-releases' } 7 | maven { url 'https://download.corda.net/maven/corda-dependencies' } 8 | maven { url 'https://repo.gradle.org/gradle/libs-releases' } 9 | } 10 | -------------------------------------------------------------------------------- /src/adhara/interop-service/corda-decoder/src/main/java/io/adhara/poc/amqp/codec/AMQPType.java: -------------------------------------------------------------------------------- 1 | package io.adhara.poc.amqp.codec; 2 | 3 | import java.util.Collection; 4 | 5 | public interface AMQPType { 6 | Class getTypeClass(); 7 | 8 | TypeEncoding getEncoding(V val); 9 | 10 | TypeEncoding getCanonicalEncoding(); 11 | 12 | Collection> getAllEncodings(); 13 | 14 | void write(V val); 15 | } 16 | -------------------------------------------------------------------------------- /src/adhara/interop-service/corda-decoder/src/main/java/io/adhara/poc/amqp/codec/PrimitiveType.java: -------------------------------------------------------------------------------- 1 | package io.adhara.poc.amqp.codec; 2 | 3 | import java.util.Collection; 4 | 5 | public interface PrimitiveType extends AMQPType { 6 | 7 | PrimitiveTypeEncoding getEncoding(V val); 8 | 9 | PrimitiveTypeEncoding getCanonicalEncoding(); 10 | 11 | Collection> getAllEncodings(); 12 | 13 | 14 | } 15 | -------------------------------------------------------------------------------- /src/adhara/interop-service/cordapp/clients/src/main/java/net/corda/samples/example/webserver/requests/CreateDCRRequest.java: -------------------------------------------------------------------------------- 1 | package net.corda.samples.example.webserver.requests; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | @Data 8 | @AllArgsConstructor 9 | @NoArgsConstructor 10 | public class CreateDCRRequest { 11 | private String value; 12 | private String currency; 13 | } 14 | -------------------------------------------------------------------------------- /src/adhara/interop-service/cordapp/repositories.gradle: -------------------------------------------------------------------------------- 1 | repositories { 2 | mavenLocal() 3 | mavenCentral() 4 | 5 | maven { url 'https://jitpack.io' } 6 | maven { url 'https://download.corda.net/maven/corda' } 7 | maven { url 'https://download.corda.net/maven/corda-dependencies' } 8 | maven { url 'https://download.corda.net/maven/corda-releases' } 9 | maven { url 'https://repo.gradle.org/gradle/libs-releases' } 10 | } 11 | -------------------------------------------------------------------------------- /src/adhara/interop-service/corda-decoder/src/main/java/io/adhara/poc/rest/DecoderService.java: -------------------------------------------------------------------------------- 1 | package io.adhara.poc.rest; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class DecoderService { 8 | public static void main(String[] args) { 9 | SpringApplication.run(DecoderService.class, args); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /docs/r3/contents.md: -------------------------------------------------------------------------------- 1 | # Interop Working Paper 2 | 3 | Table of Contents: 4 | 5 | * [Architecture Principles for Interop](architecture_principles.md) 6 | * [Problem Statement](problem_statement.md) 7 | * [Beyond "command and control"](beyond_candc.md) 8 | * [Bounded Visibility](bounded_visibility.md) 9 | * [Portable Proofs](portable_proofs.md) 10 | * [Vicarious trust](vicarious_trust.md) 11 | * [Remote Finality Guarantors](remote_finality_guarantors.md) 12 | -------------------------------------------------------------------------------- /src/adhara/interop-service/cordapp/clients/src/main/java/net/corda/samples/example/webserver/requests/ResolveXVPRequest.java: -------------------------------------------------------------------------------- 1 | package net.corda.samples.example.webserver.requests; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | @Data 8 | @AllArgsConstructor 9 | @NoArgsConstructor 10 | public class ResolveXVPRequest { 11 | private String tradeId; 12 | private String sourceNetworkId; 13 | } 14 | -------------------------------------------------------------------------------- /src/adhara/interop-service/corda-decoder/src/main/java/io/adhara/poc/amqp/codec/AMQPDefinedTypes.java: -------------------------------------------------------------------------------- 1 | package io.adhara.poc.amqp.codec; 2 | 3 | public class AMQPDefinedTypes { 4 | public static void registerAllTypes(Decoder decoder, EncoderImpl encoder) { 5 | //registerTransportTypes(decoder, encoder); 6 | //registerMessagingTypes(decoder, encoder); 7 | //registerTransactionTypes(decoder, encoder); 8 | //registerSecurityTypes(decoder, encoder); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/adhara/interop-service/crosschainInterop/api/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "scripts": { 3 | "start-admin": "node admin/index.js", 4 | "start-gendoc-admin": "node admin/swagger.js", 5 | "start-app": "node app/index.js", 6 | "start-gendoc-app": "node app/swagger.js" 7 | }, 8 | "dependencies": { 9 | "cookie-parser": "^1.4.6", 10 | "express-openapi": "^12.0.1", 11 | "swagger-ui-express": "^4.5.0", 12 | "swagger-autogen": "^2.23.1" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/adhara/interop-service/cordapp/clients/src/main/java/net/corda/samples/example/webserver/requests/EarmarkDCRRequest.java: -------------------------------------------------------------------------------- 1 | package net.corda.samples.example.webserver.requests; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | @Data 8 | @AllArgsConstructor 9 | @NoArgsConstructor 10 | public class EarmarkDCRRequest { 11 | private String linearId; 12 | private String partyName; 13 | private String tradeId; 14 | } 15 | -------------------------------------------------------------------------------- /src/adhara/interop-service/corda-decoder/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine:3.16.2 as builder 2 | 3 | WORKDIR /cordaDecoder 4 | 5 | RUN apk add openjdk11 maven 6 | 7 | COPY . /cordaDecoder 8 | 9 | RUN mvn package 10 | 11 | FROM alpine:3.16.2 12 | 13 | WORKDIR /cordaDecoder 14 | 15 | RUN apk update && apk upgrade 16 | 17 | RUN apk add openjdk11 18 | 19 | COPY --from=builder /cordaDecoder/target . 20 | 21 | ENTRYPOINT ["java" , "-jar" , "corda-decode-0.0.1-SNAPSHOT.jar"] 22 | 23 | EXPOSE 8080 -------------------------------------------------------------------------------- /src/r3/atomic-swap/evm/.gitignore: -------------------------------------------------------------------------------- 1 | # Compiler files 2 | cache/ 3 | out/ 4 | 5 | **/bin/ 6 | 7 | # Ignores development broadcast logs 8 | !/broadcast 9 | /broadcast/*/31337/ 10 | /broadcast/**/dry-run/ 11 | 12 | # Dotenv file 13 | .env 14 | 15 | # Gradle 16 | .gradle 17 | **/build/ 18 | !src/**/build/ 19 | !gradle-wrapper.jar 20 | !gradle-wrapper.properties 21 | 22 | # Web3j generated java wrappers 23 | src/main/java 24 | 25 | # Node 26 | node_modules/ 27 | 28 | # Other 29 | .DS_Store -------------------------------------------------------------------------------- /src/adhara/interop-service/corda-decoder/src/test/java/io.adhara.poc/rest/DecoderServiceTests.java: -------------------------------------------------------------------------------- 1 | package io.adhara.poc.rest; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit4.SpringRunner; 7 | 8 | @RunWith(SpringRunner.class) 9 | @SpringBootTest 10 | public class DecoderServiceTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } -------------------------------------------------------------------------------- /src/adhara/interop-service/cordapp/clients/src/main/java/net/corda/samples/example/webserver/requests/CancelDCRRequest.java: -------------------------------------------------------------------------------- 1 | package net.corda.samples.example.webserver.requests; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | @Data 8 | @AllArgsConstructor 9 | @NoArgsConstructor 10 | public class CancelDCRRequest { 11 | private String tradeId; 12 | private String encodedInfo; 13 | private String signatureOrProof; 14 | } 15 | -------------------------------------------------------------------------------- /src/adhara/interop-service/corda-decoder/src/main/java/io/adhara/poc/amqp/codec/TypeEncoding.java: -------------------------------------------------------------------------------- 1 | package io.adhara.poc.amqp.codec; 2 | 3 | public interface TypeEncoding { 4 | AMQPType getType(); 5 | 6 | void writeConstructor(); 7 | 8 | int getConstructorSize(); 9 | 10 | void writeValue(V val); 11 | 12 | int getValueSize(V val); 13 | 14 | boolean isFixedSizeVal(); 15 | 16 | boolean encodesSuperset(TypeEncoding encoder); 17 | 18 | boolean encodesJavaPrimitive(); 19 | } 20 | -------------------------------------------------------------------------------- /src/adhara/interop-service/cordapp/clients/src/main/java/net/corda/samples/example/webserver/requests/CreateXVPRequest.java: -------------------------------------------------------------------------------- 1 | package net.corda.samples.example.webserver.requests; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | @Data 8 | @AllArgsConstructor 9 | @NoArgsConstructor 10 | public class CreateXVPRequest { 11 | private String tradeId; 12 | private String assetId; 13 | private String from; 14 | private String to; 15 | } 16 | -------------------------------------------------------------------------------- /src/adhara/interop-service/cordapp/deploy/corda-network/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: corda-network 3 | description: This chart will deploy a 3 node corda network 4 | 5 | # This is an application chart that will deploy a corda network 6 | type: application 7 | 8 | # This is the version of the chart please be sure to follow Semantic Versioning (https://semver.org/) 9 | version: 0.1.0 10 | 11 | # This is the version of the application being deployed please use quotes 12 | appVersion: "1.0.0" 13 | -------------------------------------------------------------------------------- /src/adhara/interop-service/corda-decoder/src/main/java/io/adhara/poc/ledger/SignableData.java: -------------------------------------------------------------------------------- 1 | package io.adhara.poc.ledger; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | @Data 8 | @AllArgsConstructor 9 | public class SignableData { 10 | private final SecureHash txId; // Transaction's id or root of multi-transaction Merkle tree in case of multi-transaction signing 11 | private final SignedMeta signatureMeta; // Meta data required 12 | } 13 | -------------------------------------------------------------------------------- /src/adhara/interop-service/crosschainInterop/.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | .vscode/ 3 | 4 | node_modules/ 5 | 6 | *.swp 7 | 8 | proof.txt 9 | target/ 10 | bin/ 11 | build/ 12 | cache/ 13 | logs/ 14 | exported/ 15 | monitored/ 16 | file-db/ 17 | 18 | .gradle 19 | .idea 20 | *.iml 21 | *.iws 22 | *.ipr 23 | 24 | 25 | # OS generated files # 26 | .DS_Store 27 | .DS_Store? 28 | ._* 29 | .Spotlight-V100 30 | .Trashes 31 | ehthumbs.db 32 | Thumbs.db 33 | 34 | /test-integration/monitoring-bc-*/ 35 | /test-db-*/ 36 | 37 | -------------------------------------------------------------------------------- /src/adhara/interop-service/corda-decoder/src/main/java/io/adhara/poc/amqp/codec/DecodeException.java: -------------------------------------------------------------------------------- 1 | package io.adhara.poc.amqp.codec; 2 | 3 | public class DecodeException extends RuntimeException { 4 | public DecodeException() { 5 | } 6 | 7 | public DecodeException(String message) { 8 | super(message); 9 | } 10 | 11 | public DecodeException(String message, Throwable cause) { 12 | super(message, cause); 13 | } 14 | 15 | public DecodeException(Throwable cause) { 16 | super(cause); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/adhara/interop-service/corda-decoder/src/main/java/io/adhara/poc/amqp/codec/EncodeException.java: -------------------------------------------------------------------------------- 1 | package io.adhara.poc.amqp.codec; 2 | 3 | public class EncodeException extends RuntimeException { 4 | public EncodeException() { 5 | } 6 | 7 | public EncodeException(String message) { 8 | super(message); 9 | } 10 | 11 | public EncodeException(String message, Throwable cause) { 12 | super(message, cause); 13 | } 14 | 15 | public EncodeException(Throwable cause) { 16 | super(cause); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/adhara/interop-service/cordapp/deploy/corda-network/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *.orig 18 | *~ 19 | # Various IDEs 20 | .project 21 | .idea/ 22 | *.tmproj 23 | .vscode/ 24 | -------------------------------------------------------------------------------- /src/adhara/interop-service/crosschainInterop/api/app/services/repoObligationService.js: -------------------------------------------------------------------------------- 1 | function init(config, crosschainApplicationSDK){ 2 | const repoObligationService = { 3 | postRepoObligation: async function postRepoObligation(networkId, body){ 4 | console.log("createRepoObligation to crosschainApplicationSDK") 5 | return await crosschainApplicationSDK.createRepoObligation(networkId, body) 6 | } 7 | } 8 | 9 | return repoObligationService 10 | } 11 | 12 | module.exports = init 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/adhara/interop-service/cordapp/clients/Makefile: -------------------------------------------------------------------------------- 1 | PROJECT ?= corda-api 2 | TAG ?= local 3 | DOCKER_REPO ?= adhara-docker.jfrog.io/adharaprojects 4 | 5 | build: 6 | docker build -t ${DOCKER_REPO}/${PROJECT}:${TAG} \ 7 | --build-arg ARTIFACTORY_USER=${ARTIFACTORY_USER} \ 8 | --build-arg ARTIFACTORY_PASSWORD=${ARTIFACTORY_PASSWORD} \ 9 | -f ./corda-experiments/cordapp/clients/Dockerfile \ 10 | ./corda-experiments/cordapp/clients 11 | 12 | publish: build 13 | docker push ${DOCKER_REPO}/${PROJECT}:${TAG} 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/adhara/interop-service/cordapp/clients/src/main/resources/static/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Example front-end. 7 | 8 | 9 |
10 | Corda 11 |

CorDapp Template (Java Version)

12 |

Learn more about how to build CorDapps at sample-java

13 |
14 | 15 | -------------------------------------------------------------------------------- /src/adhara/interop-service/crosschainInterop/api/admin/services/validatorService.js: -------------------------------------------------------------------------------- 1 | function init(config, crosschainApplicationSDK) { 2 | const validatorService = { 3 | getValidators: async function getValidators(blockHash) { 4 | if (!!blockHash) { 5 | return await crosschainApplicationSDK.getValidatorsByBlockhash(blockHash) 6 | } else { 7 | return await crosschainApplicationSDK.getAllValidators() 8 | } 9 | } 10 | } 11 | 12 | return validatorService 13 | } 14 | 15 | 16 | module.exports = init 17 | -------------------------------------------------------------------------------- /src/adhara/interop-service/cordapp/clients/src/main/java/net/corda/samples/example/webserver/requests/ConfirmDCRRequest.java: -------------------------------------------------------------------------------- 1 | package net.corda.samples.example.webserver.requests; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | @Data 8 | @AllArgsConstructor 9 | @NoArgsConstructor 10 | public class ConfirmDCRRequest { 11 | private String tradeId; 12 | private String networkId; 13 | private String sourceNetworkId; 14 | private String encodedInfo; 15 | private String signatureOrProof; 16 | } 17 | -------------------------------------------------------------------------------- /src/adhara/interop-service/crosschainInterop/api/app/services/settlementObligationService.js: -------------------------------------------------------------------------------- 1 | function init(config, crosschainApplicationSDK){ 2 | const settlementObligationService = { 3 | postSettlementObligation: async function postSettlementObligation(networkId, body){ 4 | console.log("createSettlementObligation to crosschainApplicationSDK") 5 | return await crosschainApplicationSDK.createSettlementObligation(networkId, body) 6 | } 7 | } 8 | 9 | return settlementObligationService 10 | } 11 | 12 | module.exports = init 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/adhara/interop-service/cordapp/clients/src/main/java/net/corda/samples/example/webserver/Properties.java: -------------------------------------------------------------------------------- 1 | package net.corda.samples.example.webserver; 2 | 3 | import org.springframework.context.annotation.Configuration; 4 | import org.springframework.context.annotation.PropertySource; 5 | 6 | @Configuration 7 | @PropertySource("classpath:application.properties") 8 | public class Properties { 9 | private String config; 10 | 11 | public String getConfig() { 12 | return config; 13 | } 14 | public void setConfig(String config) { 15 | this.config = config; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/r3/atomic-swap/corda/evm-interop-contracts/src/main/kotlin/com/r3/corda/evminterop/dto/ContractInfo.kt: -------------------------------------------------------------------------------- 1 | package com.r3.corda.evminterop.dto 2 | 3 | import net.corda.core.serialization.CordaSerializable 4 | 5 | /** 6 | * Represents the deploy status of a Solidity contract. 7 | * 8 | * @property deployed indicates if there is a contract at the deployAddress or not. 9 | * @property deployAddress is the contract's current or future deployment address. 10 | */ 11 | @CordaSerializable 12 | data class ContractInfo( 13 | val deployed: Boolean, 14 | val deployAddress: String 15 | ) -------------------------------------------------------------------------------- /src/adhara/interop-service/corda-decoder/src/main/java/io/adhara/poc/amqp/codec/FastPathDescribedTypeConstructor.java: -------------------------------------------------------------------------------- 1 | package io.adhara.poc.amqp.codec; 2 | 3 | /** 4 | * Marker interface that indicates the TypeConstructor can decode known Proton-J types 5 | * using a fast path read / write operation. These types may result in an encode that 6 | * does not always write the smallest form of the given type to save time. 7 | * 8 | * @param The type that this constructor handles 9 | */ 10 | public interface FastPathDescribedTypeConstructor extends TypeConstructor { 11 | 12 | } 13 | -------------------------------------------------------------------------------- /src/adhara/interop-service/corda-decoder/src/main/java/io/adhara/poc/ledger/ComponentGroup.java: -------------------------------------------------------------------------------- 1 | package io.adhara.poc.ledger; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | 9 | import java.util.Collections; 10 | import java.util.List; 11 | 12 | @Data 13 | @AllArgsConstructor 14 | public class ComponentGroup { 15 | private final byte[] opaqueBytes; 16 | private final int groupIndex; 17 | private final int internalIndex; 18 | private final SecureHash hash; 19 | } 20 | -------------------------------------------------------------------------------- /src/adhara/interop-service/cordapp/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM corda/community:4.12-zulu-openjdk 2 | 3 | ARG CERTIFICATES 4 | ARG NETWORK_PARAMETERS 5 | ARG P2P_PORT 6 | ARG RPC_PORT 7 | ARG RPC_ADMIN_PORT 8 | 9 | COPY --chown=corda:corda entrypoint.sh /opt/corda 10 | COPY ${CERTIFICATES} /opt/corda/certificates 11 | COPY /build/nodes/Notary/cordapps /opt/corda/cordapps 12 | COPY ${NETWORK_PARAMETERS} /opt/corda/network-parameters 13 | 14 | RUN chmod +x /opt/corda/entrypoint.sh 15 | 16 | ENTRYPOINT [ "./entrypoint.sh" ] 17 | 18 | EXPOSE ${P2P_PORT} 19 | EXPOSE ${RPC_PORT} 20 | EXPOSE ${RPC_ADMIN_PORT} 21 | EXPOSE 22022 22 | -------------------------------------------------------------------------------- /src/adhara/interop-service/corda-decoder/src/main/java/io/adhara/poc/ledger/MerkleProof.java: -------------------------------------------------------------------------------- 1 | package io.adhara.poc.ledger; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | 6 | import java.util.Arrays; 7 | 8 | @Data 9 | @AllArgsConstructor 10 | public class MerkleProof { 11 | private final SecureHash[] proof; 12 | private final byte[] flags; 13 | private final SecureHash[] leaves; 14 | 15 | public boolean equals(MerkleProof other) { 16 | return Arrays.equals(proof, other.proof) 17 | && Arrays.equals(flags, other.flags) 18 | && Arrays.equals(leaves, other.leaves); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/r3/atomic-swap/evm/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Function to check if a specific port is open 4 | wait_for_port() { 5 | local port=$1 6 | while ! nc -z localhost $port; do 7 | sleep 1 8 | done 9 | } 10 | 11 | # Background task to deploy contracts once the node is ready 12 | ( 13 | echo "Waiting for Hardhat node to start on port 8545..." 14 | wait_for_port 8545 15 | 16 | echo "Deploying contracts..." 17 | npx hardhat run deploy.js --network localhost 18 | touch /app/deployment_complete 19 | ) & 20 | 21 | # Start Hardhat node in the foreground 22 | npx hardhat node 23 | -------------------------------------------------------------------------------- /src/adhara/interop-service/corda-decoder/src/main/java/io/adhara/poc/amqp/codec/LargeFloatingSizePrimitiveTypeEncoding.java: -------------------------------------------------------------------------------- 1 | package io.adhara.poc.amqp.codec; 2 | 3 | abstract class LargeFloatingSizePrimitiveTypeEncoding extends FloatingSizePrimitiveTypeEncoding { 4 | 5 | LargeFloatingSizePrimitiveTypeEncoding(final EncoderImpl encoder, DecoderImpl decoder) { 6 | super(encoder, decoder); 7 | } 8 | 9 | @Override 10 | public int getSizeBytes() { 11 | return 4; 12 | } 13 | 14 | @Override 15 | protected void writeSize(final T val) { 16 | getEncoder().writeRaw(getEncodedValueSize(val)); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/adhara/interop-service/corda-decoder/src/main/java/io/adhara/poc/amqp/codec/SmallFloatingSizePrimitiveTypeEncoding.java: -------------------------------------------------------------------------------- 1 | package io.adhara.poc.amqp.codec; 2 | 3 | abstract class SmallFloatingSizePrimitiveTypeEncoding extends FloatingSizePrimitiveTypeEncoding { 4 | 5 | SmallFloatingSizePrimitiveTypeEncoding(final EncoderImpl encoder, final DecoderImpl decoder) { 6 | super(encoder, decoder); 7 | } 8 | 9 | @Override 10 | public int getSizeBytes() { 11 | return 1; 12 | } 13 | 14 | @Override 15 | protected void writeSize(final T val) { 16 | getEncoder().writeRaw((byte) getEncodedValueSize(val)); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/adhara/interop-service/cordapp/LICENCE: -------------------------------------------------------------------------------- 1 | Copyright 2016, R3 Limited. 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. -------------------------------------------------------------------------------- /src/r3/atomic-swap/corda/evm-interop-contracts/src/main/kotlin/com/r3/corda/evminterop/dto/TokenMetadata.kt: -------------------------------------------------------------------------------- 1 | package com.r3.corda.evminterop.dto 2 | 3 | import net.corda.core.serialization.CordaSerializable 4 | import java.math.BigInteger 5 | 6 | /** 7 | * Description of an ERC20 token 8 | * 9 | * @property address the ERC20 token deployment address 10 | * @property name of the ERC20 token 11 | * @property symbol of the ERC20 token 12 | * @property decimals of the ERC20 token 13 | */ 14 | @CordaSerializable 15 | data class TokenMetadata( 16 | val address: String, 17 | val name: String, 18 | val symbol: String, 19 | val decimals: BigInteger 20 | ) -------------------------------------------------------------------------------- /src/adhara/interop-service/corda-decoder/src/main/java/io/adhara/poc/ledger/Extracted.java: -------------------------------------------------------------------------------- 1 | package io.adhara.poc.ledger; 2 | 3 | import java.util.Map; 4 | 5 | public class Extracted implements Map.Entry { 6 | private final K key; 7 | private V value; 8 | 9 | public Extracted(K key, V value) { 10 | this.key = key; 11 | this.value = value; 12 | } 13 | 14 | @Override 15 | public K getKey() { 16 | return key; 17 | } 18 | 19 | @Override 20 | public V getValue() { 21 | return value; 22 | } 23 | 24 | @Override 25 | public V setValue(V value) { 26 | V old = this.value; 27 | this.value = value; 28 | return old; 29 | } 30 | } -------------------------------------------------------------------------------- /src/adhara/interop-service/crosschainInterop/src/CrosschainSDKUtils/errors.js: -------------------------------------------------------------------------------- 1 | 2 | class CustomError extends Error { 3 | constructor(code, message, data) { 4 | super(message); 5 | // Ensure the name of this error is the same as the class name 6 | this.name = this.constructor.name; 7 | this.code = code; 8 | this.data = data; 9 | // This clips the constructor invocation from the stack trace. 10 | // It's not absolutely essential, but it does make the stack trace a little nicer. 11 | // @see Node.js reference (bottom) 12 | Error.captureStackTrace(this, this.constructor); 13 | } 14 | } 15 | 16 | module.exports = { 17 | CustomError, 18 | }; 19 | -------------------------------------------------------------------------------- /src/adhara/interop-service/crosschainInterop/contracts/test/Base64Verify.sol: -------------------------------------------------------------------------------- 1 | /* 2 | IT IS UNDERSTOOD THAT THE PROOF OF CONCEPT SOFTWARE, DOCUMENTATION, AND ANY UPDATES MAY CONTAIN ERRORS AND ARE PROVIDED FOR LIMITED EVALUATION ONLY. THE PROOF OF CONCEPT SOFTWARE, THE DOCUMENTATION, 3 | AND ANY UPDATES ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, WHETHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE. 4 | */ 5 | 6 | // SPDX-License-Identifier: Apache-2.0 7 | pragma solidity ^0.8.13; 8 | 9 | import "contracts/libraries/Base64.sol"; 10 | 11 | contract Base64Verify { 12 | function encode(bytes memory data) public pure returns (string memory) { 13 | return Base64.encode(data); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/adhara/interop-service/cordapp/workflows/src/main/resources/migration/dcr.changelog-master.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/adhara/interop-service/cordapp/workflows/src/main/resources/migration/xvp.changelog-master.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/adhara/interop-service/crosschainInterop/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:18-alpine3.15 as builder 2 | 3 | WORKDIR /crosschainInterop 4 | 5 | RUN apk add --update git python3 krb5 krb5-libs gcc make g++ krb5-dev 6 | 7 | COPY ./package.json . 8 | COPY ./package-lock.json . 9 | 10 | RUN npm i 11 | 12 | WORKDIR /crosschainInterop 13 | 14 | COPY . . 15 | 16 | RUN npx hardhat compile 17 | 18 | FROM node:18-alpine3.15 19 | 20 | RUN apk update && apk upgrade 21 | 22 | WORKDIR /crosschainInterop/api 23 | 24 | ENV PATH=${PATH}:/crosschainInterop/ethgwctl/ 25 | 26 | RUN apk --no-cache add curl 27 | 28 | COPY --from=builder /crosschainInterop /crosschainInterop 29 | 30 | ENTRYPOINT ["node" , "app/index.js"] 31 | 32 | EXPOSE 3030 33 | EXPOSE 3031 34 | -------------------------------------------------------------------------------- /src/adhara/interop-service/corda-decoder/src/main/java/io/adhara/poc/amqp/codec/FixedSizePrimitiveTypeEncoding.java: -------------------------------------------------------------------------------- 1 | package io.adhara.poc.amqp.codec; 2 | 3 | abstract class FixedSizePrimitiveTypeEncoding extends AbstractPrimitiveTypeEncoding { 4 | 5 | FixedSizePrimitiveTypeEncoding(final EncoderImpl encoder, final DecoderImpl decoder) { 6 | super(encoder, decoder); 7 | } 8 | 9 | public final boolean isFixedSizeVal() { 10 | return true; 11 | } 12 | 13 | public final int getValueSize(final T val) { 14 | return getFixedSize(); 15 | } 16 | 17 | public final void skipValue() { 18 | getDecoder().getBuffer().position(getDecoder().getBuffer().position() + getFixedSize()); 19 | } 20 | 21 | protected abstract int getFixedSize(); 22 | } 23 | -------------------------------------------------------------------------------- /src/adhara/interop-service/cordapp/contracts/src/test/java/net/corda/samples/example/contracts/StateTests.java: -------------------------------------------------------------------------------- 1 | package net.corda.samples.example.contracts; 2 | 3 | import net.corda.samples.example.states.DCRState; 4 | import net.corda.testing.node.MockServices; 5 | import org.junit.Test; 6 | 7 | public class StateTests { 8 | private final MockServices ledgerServices = new MockServices(); 9 | 10 | @Test 11 | public void hasAmountFieldOfCorrectType() throws NoSuchFieldException { 12 | // Does the message field exist? 13 | DCRState.class.getDeclaredField("value"); 14 | // Is the message field of the correct type? 15 | assert(DCRState.class.getDeclaredField("value").getType().equals(String.class)); 16 | } 17 | } -------------------------------------------------------------------------------- /src/adhara/interop-service/cordapp/clients/src/main/java/net/corda/samples/example/webserver/Starter.java: -------------------------------------------------------------------------------- 1 | package net.corda.samples.example.webserver; 2 | 3 | import org.springframework.boot.Banner; 4 | import org.springframework.boot.SpringApplication; 5 | import org.springframework.boot.autoconfigure.SpringBootApplication; 6 | 7 | import java.util.HashMap; 8 | 9 | import static org.springframework.boot.WebApplicationType.SERVLET; 10 | 11 | @SpringBootApplication 12 | public class Starter { 13 | 14 | public static void main(String[] args) { 15 | SpringApplication app = new SpringApplication(Starter.class); 16 | app.setBannerMode(Banner.Mode.OFF); 17 | app.setWebApplicationType(SERVLET); 18 | app.run(args); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/adhara/interop-service/cordapp/config/test/log4j2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | [%-5level] %d{HH:mm:ss.SSS} [%t] %c{1}.%M - %msg%n 8 | > 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/adhara/interop-service/crosschainInterop/src/CrosschainApplicationSDK/settlementInstructionStates.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | confirmed: 'confirmed', 3 | waitingForHold: 'waitingForHold', 4 | waitingForCrosschainFunctionCall: 'waitingForCrosschainFunctionCall', 5 | waitingForRemoteNetworkCancellation: 'waitingForRemoteNetworkCancellation', 6 | waitingForExecuteHoldExecuted: 'waitingForExecuteHoldExecuted', 7 | waitingForCancelHoldExecuted: 'waitingForCancelHoldExecuted', 8 | waitingForCommunication: 'waitingForCommunication', 9 | timedOutCommunication: 'timedOutCommunication', 10 | processed: 'processed', 11 | failed: 'failed', 12 | timedOut: 'timedOut', 13 | cancel: 'cancel', 14 | cancelling: 'cancelling', 15 | cancelled: 'cancelled' 16 | } 17 | -------------------------------------------------------------------------------- /src/adhara/interop-service/corda-decoder/Makefile: -------------------------------------------------------------------------------- 1 | PROJECT ?= corda-decoder 2 | TAG ?= local 3 | DOCKER_REPO ?= adhara-docker.jfrog.io/adharaprojects 4 | 5 | build: 6 | docker build -t ${DOCKER_REPO}/${PROJECT}:${TAG} \ 7 | --build-arg ARTIFACTORY_USER=${ARTIFACTORY_USER} \ 8 | --build-arg ARTIFACTORY_PASSWORD=${ARTIFACTORY_PASSWORD} \ 9 | -f ./corda-experiments/corda-decoder/Dockerfile \ 10 | ./corda-experiments/corda-decoder 11 | 12 | publish: build 13 | docker push ${DOCKER_REPO}/${PROJECT}:${TAG} 14 | 15 | scan: 16 | @echo "Scanning docker image" 17 | trivy image --exit-code 0 --severity "UNKNOWN,LOW" --no-progress ${DOCKER_REPO}/${PROJECT}:${TAG} 18 | trivy image --exit-code 0 --severity "MEDIUM,HIGH,CRITICAL" --no-progress ${DOCKER_REPO}/${PROJECT}:${TAG} -------------------------------------------------------------------------------- /src/r3/atomic-swap/evm/.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: test 2 | 3 | on: workflow_dispatch 4 | 5 | env: 6 | FOUNDRY_PROFILE: ci 7 | 8 | jobs: 9 | check: 10 | strategy: 11 | fail-fast: true 12 | 13 | name: Foundry project 14 | runs-on: ubuntu-latest 15 | steps: 16 | - uses: actions/checkout@v3 17 | with: 18 | submodules: recursive 19 | 20 | - name: Install Foundry 21 | uses: foundry-rs/foundry-toolchain@v1 22 | with: 23 | version: nightly 24 | 25 | - name: Run Forge build 26 | run: | 27 | forge --version 28 | forge build --sizes 29 | id: build 30 | 31 | - name: Run Forge tests 32 | run: | 33 | forge test -vvv 34 | id: test 35 | -------------------------------------------------------------------------------- /src/adhara/interop-service/besu/services/docker-compose-1.yaml: -------------------------------------------------------------------------------- 1 | version: '3.5' 2 | networks: 3 | default: 4 | name: default1 5 | services: 6 | besu1: 7 | image: hyperledger/besu:23.7.2 8 | command: 9 | - --config-file 10 | - /etc/besu/besu.conf 11 | - --genesis-file 12 | - /etc/besu/genesis.json 13 | - --data-path 14 | - /var/lib/besu/data 15 | - --rpc-http-host 16 | - 0.0.0.0 17 | - --rpc-ws-host 18 | - 0.0.0.0 19 | - --metrics-host 20 | - 0.0.0.0 21 | - --p2p-host 22 | - 0.0.0.0 23 | volumes: 24 | - "./config.toml:/etc/besu/besu.conf" 25 | - "./node-1/data:/var/lib/besu/data" 26 | - "./genesis-1.json:/etc/besu/genesis.json" 27 | ports: 28 | - "8545:8545" 29 | -------------------------------------------------------------------------------- /src/adhara/interop-service/besu/services/docker-compose-2.yaml: -------------------------------------------------------------------------------- 1 | version: '3.5' 2 | networks: 3 | default: 4 | name: default2 5 | services: 6 | besu2: 7 | image: hyperledger/besu:23.7.2 8 | command: 9 | - --config-file 10 | - /etc/besu/besu.conf 11 | - --genesis-file 12 | - /etc/besu/genesis.json 13 | - --data-path 14 | - /var/lib/besu/data 15 | - --rpc-http-host 16 | - 0.0.0.0 17 | - --rpc-ws-host 18 | - 0.0.0.0 19 | - --metrics-host 20 | - 0.0.0.0 21 | - --p2p-host 22 | - 0.0.0.0 23 | volumes: 24 | - "./config.toml:/etc/besu/besu.conf" 25 | - "./node-2/data:/var/lib/besu/data" 26 | - "./genesis-2.json:/etc/besu/genesis.json" 27 | ports: 28 | - "7545:8545" 29 | -------------------------------------------------------------------------------- /src/adhara/interop-service/corda-decoder/src/main/java/io/adhara/poc/amqp/codec/NullElement.java: -------------------------------------------------------------------------------- 1 | package io.adhara.poc.amqp.codec; 2 | 3 | import java.nio.ByteBuffer; 4 | 5 | class NullElement extends AtomicElement { 6 | NullElement(Element parent, Element prev) { 7 | super(parent, prev); 8 | } 9 | 10 | @Override 11 | public int size() { 12 | return isElementOfArray() ? 0 : 1; 13 | } 14 | 15 | @Override 16 | public Void getValue() { 17 | return null; 18 | } 19 | 20 | @Override 21 | public Data.DataType getDataType() { 22 | return Data.DataType.NULL; 23 | } 24 | 25 | @Override 26 | public int encode(ByteBuffer b) { 27 | if (b.hasRemaining() && !isElementOfArray()) { 28 | b.put((byte) 0x40); 29 | return 1; 30 | } 31 | return 0; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/r3/atomic-swap/corda/evm-interop-contracts/src/main/kotlin/com/r3/corda/evminterop/states/swap/UnlockData.kt: -------------------------------------------------------------------------------- 1 | package com.r3.corda.evminterop.states.swap 2 | 3 | import com.r3.corda.evminterop.dto.TransactionReceipt 4 | import com.r3.corda.interop.evm.common.trie.SimpleKeyValueStore 5 | import net.corda.core.crypto.DigitalSignature 6 | import net.corda.core.serialization.CordaSerializable 7 | 8 | /** 9 | * Defines the data structure containing the parameters required to unlock a Corda transaction using an EVM event proofs 10 | */ 11 | @CordaSerializable 12 | data class UnlockData( 13 | val merkleProof: SimpleKeyValueStore, 14 | val validatorSignatures: List, 15 | val receiptsRootHash: String, 16 | val transactionReceipt: TransactionReceipt 17 | ) -------------------------------------------------------------------------------- /src/r3/atomic-swap/corda/evm-interop-workflows/src/main/kotlin/com/r3/corda/evminterop/services/IBridge.kt: -------------------------------------------------------------------------------- 1 | package com.r3.corda.evminterop.services 2 | 3 | import com.r3.corda.evminterop.dto.ContractInfo 4 | import com.r3.corda.evminterop.dto.TokenSetup 5 | import com.r3.corda.evminterop.dto.TransactionReceipt 6 | import net.corda.core.flows.FlowExternalOperation 7 | import java.math.BigInteger 8 | 9 | interface IContracts { 10 | fun deployReverseERC20(chainId: BigInteger, salt: ByteArray, initCode: ByteArray) : ResponseOperation 11 | 12 | fun deployReverseERC20(chainId: BigInteger, salt: ByteArray, setup: TokenSetup) : ResponseOperation 13 | 14 | fun getReverseERC20Address(chainId: BigInteger, salt: ByteArray): FlowExternalOperation 15 | } -------------------------------------------------------------------------------- /src/adhara/interop-service/corda-decoder/src/main/java/io/adhara/poc/amqp/codec/Element.java: -------------------------------------------------------------------------------- 1 | package io.adhara.poc.amqp.codec; 2 | 3 | import java.nio.ByteBuffer; 4 | 5 | interface Element { 6 | int size(); 7 | 8 | T getValue(); 9 | 10 | Data.DataType getDataType(); 11 | 12 | int encode(ByteBuffer b); 13 | 14 | Element next(); 15 | 16 | Element prev(); 17 | 18 | Element child(); 19 | 20 | Element parent(); 21 | 22 | void setNext(Element elt); 23 | 24 | void setPrev(Element elt); 25 | 26 | void setParent(Element elt); 27 | 28 | void setChild(Element elt); 29 | 30 | Element replaceWith(Element elt); 31 | 32 | Element addChild(Element element); 33 | 34 | Element checkChild(Element element); 35 | 36 | boolean canEnter(); 37 | 38 | void render(StringBuilder sb); 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/r3/atomic-swap/evm/Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax=docker/dockerfile:1.4 2 | FROM ghcr.io/foundry-rs/foundry:latest 3 | 4 | # Install Node.js 16, npm, and netcat using apk 5 | RUN apk --no-cache add nodejs npm netcat-openbsd 6 | 7 | # Set the working directory in the container 8 | WORKDIR /app 9 | 10 | # Copy your project into the container 11 | COPY . /app 12 | 13 | # Install project dependencies 14 | RUN forge install --no-git 15 | RUN npm install 16 | 17 | # Create a custom entry point script 18 | RUN chmod 777 /app/entrypoint.sh 19 | 20 | EXPOSE 8545 21 | 22 | HEALTHCHECK --interval=5s --timeout=5s --start-period=5s --retries=36 \ 23 | CMD [ "sh", "-c", "test -f /app/deployment_complete" ] 24 | 25 | # Start the Foundry Forge (in the background) and Hardhat Node 26 | ENTRYPOINT ["/app/entrypoint.sh"] 27 | -------------------------------------------------------------------------------- /src/adhara/interop-service/cordapp/deploy/corda-network/templates/configmap.yaml: -------------------------------------------------------------------------------- 1 | {{- if eq .Release.Name "corda-network-notary" }} 2 | kind: ConfigMap 3 | apiVersion: v1 4 | metadata: 5 | name: {{ .Values.corda.configMap.notary }} 6 | data: 7 | node.conf: | 8 | {{ .Values.notary.config | indent 4}} 9 | {{- end }} 10 | --- 11 | {{- if eq .Release.Name "corda-network-partya" }} 12 | kind: ConfigMap 13 | apiVersion: v1 14 | metadata: 15 | name: {{ .Values.corda.configMap.partya }} 16 | data: 17 | node.conf: | 18 | {{ .Values.partya.config | indent 4}} 19 | {{- end }} 20 | --- 21 | {{- if eq .Release.Name "corda-network-partyb" }} 22 | kind: ConfigMap 23 | apiVersion: v1 24 | metadata: 25 | name: {{ .Values.corda.configMap.partyb }} 26 | data: 27 | node.conf: | 28 | {{ .Values.partyb.config | indent 4}} 29 | {{- end }} -------------------------------------------------------------------------------- /src/adhara/interop-service/crosschainInterop/api/admin/services/cordaNotaryService.js: -------------------------------------------------------------------------------- 1 | function init(config, crosschainApplicationSDK){ 2 | const service = { 3 | getCordaNotary: async function getCordaNotary(networkId, remoteNetworkId, publicKey){ 4 | return await crosschainApplicationSDK.isCordaNotary(networkId, remoteNetworkId, publicKey) 5 | }, 6 | postCordaNotary: async function postCordaNotary(networkId, body){ 7 | return await crosschainApplicationSDK.addCordaNotary(networkId, body.remoteNetworkId, body.publicKey) 8 | }, 9 | deleteCordaNotary: async function deleteCordaNotary(networkId, remoteNetworkId, publicKey){ 10 | return await crosschainApplicationSDK.removeCordaNotary(networkId, remoteNetworkId, publicKey) 11 | } 12 | } 13 | 14 | return service 15 | } 16 | 17 | module.exports = init 18 | -------------------------------------------------------------------------------- /src/adhara/interop-service/crosschainInterop/contracts/test/X509Verify.sol: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | IT IS UNDERSTOOD THAT THE PROOF OF CONCEPT SOFTWARE, DOCUMENTATION, AND ANY UPDATES MAY CONTAIN ERRORS AND ARE PROVIDED FOR LIMITED EVALUATION ONLY. THE PROOF OF CONCEPT SOFTWARE, THE DOCUMENTATION, 4 | AND ANY UPDATES ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, WHETHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE. 5 | */ 6 | 7 | // SPDX-License-Identifier: MIT 8 | pragma solidity ^0.8.13; 9 | 10 | import "contracts/libraries/X509.sol"; 11 | 12 | contract X509Verify { 13 | function decodeKey( 14 | string memory h 15 | ) public view returns (bytes memory) { 16 | return X509.decodeKey(h); 17 | } 18 | 19 | function decodeKeyPayable( 20 | string memory h 21 | ) public returns (bytes memory) { 22 | return X509.decodeKey(h); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/adhara/interop-service/crosschainInterop/api/admin/services/cordaParticipantService.js: -------------------------------------------------------------------------------- 1 | function init(config, crosschainApplicationSDK){ 2 | const service = { 3 | getCordaParticipant: async function getCordaParticipant(networkId, remoteNetworkId, publicKey){ 4 | return await crosschainApplicationSDK.isCordaParticipant(networkId, remoteNetworkId, publicKey) 5 | }, 6 | postCordaParticipant: async function postCordaParticipant(networkId, body){ 7 | return await crosschainApplicationSDK.addCordaParticipant(networkId, body.remoteNetworkId, body.publicKey) 8 | }, 9 | deleteCordaParticipant: async function deleteCordaParticipant(networkId, remoteNetworkId, publicKey){ 10 | return await crosschainApplicationSDK.removeCordaParticipant(networkId, remoteNetworkId, publicKey) 11 | } 12 | } 13 | 14 | return service 15 | } 16 | 17 | module.exports = init 18 | -------------------------------------------------------------------------------- /src/adhara/interop-service/crosschainInterop/api/admin/services/validatorSetService.js: -------------------------------------------------------------------------------- 1 | 2 | function init(config, crosschainApplicationSDK){ 3 | const validatorSetService = { 4 | getValidatorSetInstruction: async function getValidatorSetInstruction(networkId, operationId) { 5 | return await crosschainApplicationSDK.getValidatorSetInstruction(networkId, operationId) 6 | }, 7 | postValidatorSetInstruction: async function postValidatorSetInstruction(networkId, body) { 8 | return await crosschainApplicationSDK.submitValidatorSetInstruction(networkId, body) 9 | }, 10 | deleteValidatorSetInstruction: async function deleteValidatorSetInstruction(networkId, operationId) { 11 | return await crosschainApplicationSDK.deleteValidatorSetInstruction(networkId, operationId) 12 | }, 13 | } 14 | return validatorSetService 15 | } 16 | 17 | module.exports = init 18 | 19 | -------------------------------------------------------------------------------- /src/r3/atomic-swap/corda/evm-interop-contracts/src/main/kotlin/com/r3/corda/evminterop/dto/TokenSetup.kt: -------------------------------------------------------------------------------- 1 | package com.r3.corda.evminterop.dto 2 | 3 | import net.corda.core.serialization.CordaSerializable 4 | import java.math.BigInteger 5 | 6 | /** 7 | * Description of an ERC20 account balance 8 | * 9 | * @property amount of the ERC20 token 10 | * @property recipient of the ERC20 token balance 11 | */ 12 | @CordaSerializable 13 | data class TokenBalance(val amount: BigInteger, val recipient: String) 14 | 15 | /** 16 | * Description of an ERC20 token at deployment 17 | * 18 | * @property tokenName the ERC20 token long name 19 | * @property tokenSymbol the ERC20 token short name 20 | * @property balances of the ERC20 token (how the initial supply is distributed) 21 | */ 22 | @CordaSerializable 23 | data class TokenSetup(val tokenName: String, val tokenSymbol: String, val balances: List) -------------------------------------------------------------------------------- /src/adhara/interop-service/corda-decoder/src/main/java/io/adhara/poc/amqp/codec/CharElement.java: -------------------------------------------------------------------------------- 1 | package io.adhara.poc.amqp.codec; 2 | 3 | import java.nio.ByteBuffer; 4 | 5 | class CharElement extends AtomicElement { 6 | 7 | private final int _value; 8 | 9 | CharElement(Element parent, Element prev, int i) { 10 | super(parent, prev); 11 | _value = i; 12 | } 13 | 14 | @Override 15 | public int size() { 16 | return isElementOfArray() ? 4 : 5; 17 | } 18 | 19 | @Override 20 | public Integer getValue() { 21 | return _value; 22 | } 23 | 24 | @Override 25 | public Data.DataType getDataType() { 26 | return Data.DataType.CHAR; 27 | } 28 | 29 | @Override 30 | public int encode(ByteBuffer b) { 31 | final int size = size(); 32 | if (size <= b.remaining()) { 33 | if (size == 5) { 34 | b.put((byte) 0x73); 35 | } 36 | b.putInt(_value); 37 | } 38 | return 0; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/adhara/interop-service/corda-decoder/src/main/java/io/adhara/poc/amqp/codec/FloatingSizePrimitiveTypeEncoding.java: -------------------------------------------------------------------------------- 1 | package io.adhara.poc.amqp.codec; 2 | 3 | abstract class FloatingSizePrimitiveTypeEncoding extends AbstractPrimitiveTypeEncoding { 4 | 5 | FloatingSizePrimitiveTypeEncoding(final EncoderImpl encoder, final DecoderImpl decoder) { 6 | super(encoder, decoder); 7 | } 8 | 9 | public final boolean isFixedSizeVal() { 10 | return false; 11 | } 12 | 13 | abstract int getSizeBytes(); 14 | 15 | public void writeValue(final T val) { 16 | writeSize(val); 17 | writeEncodedValue(val); 18 | } 19 | 20 | protected abstract void writeEncodedValue(final T val); 21 | 22 | protected abstract void writeSize(final T val); 23 | 24 | public int getValueSize(final T val) { 25 | return getSizeBytes() + getEncodedValueSize(val); 26 | } 27 | 28 | protected abstract int getEncodedValueSize(final T val); 29 | } 30 | -------------------------------------------------------------------------------- /src/adhara/interop-service/crosschainInterop/api/admin/services/validatorUpdateService.js: -------------------------------------------------------------------------------- 1 | 2 | function init(config, crosschainApplicationSDK){ 3 | const validatorUpdateService = { 4 | getValidatorUpdateInstruction: async function getValidatorUpdateInstruction(networkId, operationId) { 5 | return await crosschainApplicationSDK.getValidatorUpdateInstruction(networkId, operationId) 6 | }, 7 | postValidatorUpdateInstruction: async function postValidatorUpdateInstruction(networkId, body) { 8 | return await crosschainApplicationSDK.submitValidatorUpdateInstruction(networkId, body) 9 | }, 10 | deleteValidatorUpdateInstruction: async function deleteValidatorUpdateInstruction(networkId, operationId) { 11 | return await crosschainApplicationSDK.deleteValidatorUpdateInstruction(networkId, operationId) 12 | }, 13 | } 14 | return validatorUpdateService 15 | } 16 | 17 | module.exports = init 18 | 19 | -------------------------------------------------------------------------------- /src/r3/atomic-swap/corda/evm-interop-contracts/src/main/kotlin/com/r3/corda/evminterop/dto/TokenMetadataWithBalance.kt: -------------------------------------------------------------------------------- 1 | package com.r3.corda.evminterop.dto 2 | 3 | import net.corda.core.serialization.CordaSerializable 4 | import java.math.BigInteger 5 | 6 | /** 7 | * Description of an ERC20 token with Ethereum and Corda balance. 8 | * 9 | * @property address the ERC20 token deployment address 10 | * @property name of the ERC20 token 11 | * @property symbol of the ERC20 token 12 | * @property decimals of the ERC20 token 13 | * @property balance of the user for the ERC20 token 14 | * @property wrappedBalance of the user, in wrapped-tokens, for the ERC20 token 15 | */ 16 | @CordaSerializable 17 | data class TokenMetadataWithBalance( 18 | val address: String, 19 | val name: String, 20 | val symbol: String, 21 | val decimals: BigInteger, 22 | val balance: BigInteger, 23 | val wrappedBalance: BigInteger 24 | ) -------------------------------------------------------------------------------- /src/adhara/interop-service/cordapp/Makefile: -------------------------------------------------------------------------------- 1 | PROJECT ?= corda-node 2 | TAG ?= local 3 | DOCKER_REPO ?= adhara-docker.jfrog.io/adharaprojects 4 | CERTIFICATES_PATH ?= /build/nodes/Notary/certificates 5 | NETWORK_PARAMETERS ?= /build/nodes/Notary/network-parameters 6 | P2P_PORT ?= 10002 7 | RPC_PORT ?= 10003 8 | RPC_ADMIN_PORT ?= 10043 9 | 10 | build: 11 | docker build -t ${DOCKER_REPO}/${PROJECT}:${TAG} \ 12 | --build-arg ARTIFACTORY_USER=${ARTIFACTORY_USER} \ 13 | --build-arg ARTIFACTORY_PASSWORD=${ARTIFACTORY_PASSWORD} \ 14 | --build-arg CERTIFICATES=${CERTIFICATES_PATH} \ 15 | --build-arg NETWORK_PARAMETERS=${NETWORK_PARAMETERS} \ 16 | --build-arg P2P_PORT=${P2P_PORT} \ 17 | --build-arg RPC_PORT=${RPC_PORT} \ 18 | --build-arg RPC_ADMIN_PORT=${RPC_ADMIN_PORT} \ 19 | -f ./corda-experiments/cordapp/Dockerfile \ 20 | ./corda-experiments/cordapp 21 | 22 | publish: build 23 | docker push ${DOCKER_REPO}/${PROJECT}:${TAG} -------------------------------------------------------------------------------- /src/r3/atomic-swap/corda/evm-interop-workflows/src/main/kotlin/com/r3/corda/evminterop/services/internal/RemoteEVMIdentityImpl.kt: -------------------------------------------------------------------------------- 1 | package com.r3.corda.evminterop.services.internal 2 | 3 | import co.paralleluniverse.fibers.Suspendable 4 | import com.r3.corda.evminterop.services.IdentityServiceProvider 5 | import com.r3.corda.evminterop.services.RemoteEVMIdentity 6 | import net.corda.core.flows.FlowLogic 7 | import java.net.URI 8 | import java.security.PublicKey 9 | 10 | abstract class RemoteEVMIdentityImpl( 11 | override val rpcEndpoint: URI, 12 | override val chainId: Long, 13 | override val protocolAddress: String, 14 | override val deployerAddress: String 15 | ) : RemoteEVMIdentity { 16 | 17 | @Suspendable 18 | override fun authorize(flowLogic: FlowLogic<*>, authorizedId: PublicKey) { 19 | flowLogic.serviceHub.cordaService(IdentityServiceProvider::class.java).authorize(this, authorizedId) 20 | } 21 | } -------------------------------------------------------------------------------- /src/adhara/interop-service/crosschainInterop/contracts/interfaces/IFeeManager.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.8.13; 2 | 3 | interface IFeeManager { 4 | 5 | /* 6 | * Adds a zero cost contract, which will exempt this address from paying fees. Will fail if there is no contract at the provided address. 7 | * @param contractAddress The address of the contract to exempt from paying fees 8 | * @return A boolean indicating successful execution of the function 9 | * @dev If successful, emits AddZeroCostContractExecuted(address contractAddress); 10 | */ 11 | function addZeroCostContract( 12 | address contractAddress 13 | ) external virtual returns (bool); 14 | 15 | /* 16 | * Gets all the zero cost contract addresses. 17 | * @return zeroCostContractArray An address[] with all the zero cost contract addresses. 18 | */ 19 | function getZeroCostContracts() external view returns (address[] memory zeroCostContractArray); 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/r3/atomic-swap/corda/evm-interop-workflows/src/main/kotlin/com/r3/corda/evminterop/workflows/swap/CommitmentHash.kt: -------------------------------------------------------------------------------- 1 | package com.r3.corda.evminterop.workflows.swap 2 | 3 | import co.paralleluniverse.fibers.Suspendable 4 | import com.r3.corda.evminterop.services.evmInterop 5 | import net.corda.core.crypto.SecureHash 6 | import net.corda.core.flows.FlowLogic 7 | import net.corda.core.flows.InitiatingFlow 8 | import net.corda.core.flows.StartableByRPC 9 | import org.web3j.utils.Numeric 10 | 11 | /** 12 | * 13 | */ 14 | @StartableByRPC 15 | @InitiatingFlow 16 | class CommitmentHash( 17 | private val transactionId: SecureHash 18 | ) : FlowLogic() { 19 | 20 | @Suspendable 21 | override fun call(): String { 22 | 23 | val swapProvider = evmInterop().swapProvider() 24 | 25 | val hash = await(swapProvider.commitmentHash(transactionId.toString())) 26 | 27 | return Numeric.toHexString(hash) 28 | } 29 | } -------------------------------------------------------------------------------- /src/adhara/interop-service/corda-decoder/src/main/java/io/adhara/poc/amqp/codec/FloatElement.java: -------------------------------------------------------------------------------- 1 | package io.adhara.poc.amqp.codec; 2 | 3 | import java.nio.ByteBuffer; 4 | 5 | class FloatElement extends AtomicElement { 6 | 7 | private final float _value; 8 | 9 | FloatElement(Element parent, Element prev, float f) { 10 | super(parent, prev); 11 | _value = f; 12 | } 13 | 14 | @Override 15 | public int size() { 16 | return isElementOfArray() ? 4 : 5; 17 | } 18 | 19 | @Override 20 | public Float getValue() { 21 | return _value; 22 | } 23 | 24 | @Override 25 | public Data.DataType getDataType() { 26 | return Data.DataType.FLOAT; 27 | } 28 | 29 | @Override 30 | public int encode(ByteBuffer b) { 31 | int size = size(); 32 | if (b.remaining() >= size) { 33 | if (size == 5) { 34 | b.put((byte) 0x72); 35 | } 36 | b.putFloat(_value); 37 | return size; 38 | } else { 39 | return 0; 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/adhara/interop-service/corda-decoder/src/main/java/io/adhara/poc/amqp/codec/DoubleElement.java: -------------------------------------------------------------------------------- 1 | package io.adhara.poc.amqp.codec; 2 | 3 | import java.nio.ByteBuffer; 4 | 5 | class DoubleElement extends AtomicElement { 6 | 7 | private final double _value; 8 | 9 | DoubleElement(Element parent, Element prev, double d) { 10 | super(parent, prev); 11 | _value = d; 12 | } 13 | 14 | @Override 15 | public int size() { 16 | return isElementOfArray() ? 8 : 9; 17 | } 18 | 19 | @Override 20 | public Double getValue() { 21 | return _value; 22 | } 23 | 24 | @Override 25 | public Data.DataType getDataType() { 26 | return Data.DataType.DOUBLE; 27 | } 28 | 29 | @Override 30 | public int encode(ByteBuffer b) { 31 | int size = size(); 32 | if (b.remaining() >= size) { 33 | if (size == 9) { 34 | b.put((byte) 0x82); 35 | } 36 | b.putDouble(_value); 37 | return size; 38 | } else { 39 | return 0; 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/adhara/interop-service/crosschainInterop/api/admin/services/interopAuthParamService.js: -------------------------------------------------------------------------------- 1 | 2 | function init(config, crosschainApplicationSDK) { 3 | const interopAuthParamService = { 4 | getInteropAuthParams: async function getInteropAuthParams(networkId, remoteNetworkId, remoteContractAddress) { 5 | return await crosschainApplicationSDK.isAuthParams(networkId, remoteNetworkId, remoteContractAddress) 6 | }, 7 | postInteropAuthParams: async function postInteropAuthParams(networkId, body) { 8 | return await crosschainApplicationSDK.addAuthParams(networkId, body.remoteNetworkId, body.remoteContractAddress) 9 | }, 10 | deleteInteropAuthParams: async function deleteInteropAuthParams(networkId, body) { 11 | return await crosschainApplicationSDK.removeAuthParams(networkId, body.remoteNetworkId, body.remoteContractAddress) 12 | } 13 | } 14 | 15 | return interopAuthParamService 16 | } 17 | 18 | module.exports = init 19 | 20 | -------------------------------------------------------------------------------- /src/adhara/interop-service/crosschainInterop/api/admin/services/interopParticipantService.js: -------------------------------------------------------------------------------- 1 | 2 | function init(config, crosschainApplicationSDK){ 3 | const interopParticipantService = { 4 | getLocalAccountId: async function getInteropParticipants(networkId, remoteAccountId){ 5 | return await crosschainApplicationSDK.getRemoteAccountIdToLocalAccountId(networkId, {remoteAccountId}) 6 | }, 7 | postInteropParticipants: async function postInteropParticipants(networkId, body){ 8 | return await crosschainApplicationSDK.setRemoteAccountIdToLocalAccountId(networkId, body) 9 | }, 10 | deleteInteropParticipants: async function deleteInteropParticipants(networkId, body){ 11 | // todo - add function to remove the mapping 12 | return await crosschainApplicationSDK.getRemoteAccountIdToLocalAccountId(networkId, {remoteAccountId}) 13 | } 14 | } 15 | 16 | return interopParticipantService 17 | } 18 | 19 | module.exports = init 20 | 21 | -------------------------------------------------------------------------------- /src/adhara/interop-service/crosschainInterop/src/CrosschainApplicationSDK/repoObligations.js: -------------------------------------------------------------------------------- 1 | function init(dependencies) { 2 | 3 | async function createRepoObligation(networkId, body) { 4 | 5 | const openingLeg = { 6 | tradeId: body.tradeId, 7 | fromAccount: body.openingLeg.fromAccount, 8 | toAccount: body.openingLeg.toAccount, 9 | amount: body.openingLeg.amount 10 | } 11 | 12 | const closingLeg = { 13 | tradeId: body.tradeId, 14 | fromAccount: body.closingLeg.fromAccount, 15 | toAccount: body.closingLeg.toAccount, 16 | amount: body.closingLeg.amount, 17 | timestamp: body.closingLeg.timestamp 18 | } 19 | 20 | // Don't wait for the closing leg 21 | dependencies.createSettlementObligation(networkId, closingLeg) 22 | return await dependencies.createSettlementObligation(networkId, openingLeg) 23 | } 24 | 25 | return { 26 | createRepoObligation 27 | } 28 | } 29 | 30 | module.exports = init 31 | -------------------------------------------------------------------------------- /src/adhara/interop-service/corda-decoder/src/main/java/io/adhara/poc/amqp/codec/TimestampElement.java: -------------------------------------------------------------------------------- 1 | package io.adhara.poc.amqp.codec; 2 | 3 | import java.nio.ByteBuffer; 4 | import java.util.Date; 5 | 6 | class TimestampElement extends AtomicElement { 7 | 8 | private final Date _value; 9 | 10 | TimestampElement(Element parent, Element prev, Date d) { 11 | super(parent, prev); 12 | _value = d; 13 | } 14 | 15 | @Override 16 | public int size() { 17 | return isElementOfArray() ? 8 : 9; 18 | } 19 | 20 | @Override 21 | public Date getValue() { 22 | return _value; 23 | } 24 | 25 | @Override 26 | public Data.DataType getDataType() { 27 | return Data.DataType.TIMESTAMP; 28 | } 29 | 30 | @Override 31 | public int encode(ByteBuffer b) { 32 | int size = size(); 33 | if (size > b.remaining()) { 34 | return 0; 35 | } 36 | if (size == 9) { 37 | b.put((byte) 0x83); 38 | } 39 | b.putLong(_value.getTime()); 40 | 41 | return size; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/r3/atomic-swap/corda/evm-interop-workflows/src/main/kotlin/com/r3/corda/evminterop/workflows/swap/RevertCommitment.kt: -------------------------------------------------------------------------------- 1 | package com.r3.corda.evminterop.workflows.swap 2 | 3 | import co.paralleluniverse.fibers.Suspendable 4 | import com.r3.corda.evminterop.dto.TransactionReceipt 5 | import com.r3.corda.evminterop.services.evmInterop 6 | import net.corda.core.crypto.SecureHash 7 | import net.corda.core.flows.FlowLogic 8 | import net.corda.core.flows.InitiatingFlow 9 | import net.corda.core.flows.StartableByRPC 10 | 11 | /** 12 | * 13 | */ 14 | @StartableByRPC 15 | @InitiatingFlow 16 | class RevertCommitment( 17 | private val transactionId: SecureHash 18 | ) : FlowLogic() { 19 | 20 | @Suspendable 21 | override fun call(): TransactionReceipt { 22 | 23 | val swapProvider = evmInterop().swapProvider() 24 | 25 | val txReceipt = await(swapProvider.revertCommitment(transactionId.toString())) 26 | 27 | return txReceipt 28 | } 29 | } -------------------------------------------------------------------------------- /src/r3/atomic-swap/corda/evm-interop-workflows/src/main/kotlin/com/r3/corda/evminterop/services/ConnectionId.kt: -------------------------------------------------------------------------------- 1 | package com.r3.corda.evminterop.services 2 | 3 | import java.net.URI 4 | 5 | /** 6 | * [ConnectionId] is the key correlation between a [Session] and its [Connection] 7 | */ 8 | data class ConnectionId( 9 | val rpcEndpoint: URI, 10 | val chainId: Long 11 | ) { 12 | companion object { 13 | val httpRegex = Regex("^https?$", RegexOption.IGNORE_CASE) 14 | val wsRegex = Regex("^wss?$", RegexOption.IGNORE_CASE) 15 | } 16 | 17 | val isHttp: Boolean = httpRegex.matches(rpcEndpoint.scheme) 18 | val isWebsocket: Boolean = wsRegex.matches(rpcEndpoint.scheme) 19 | 20 | init { 21 | require(isHttp || isWebsocket) {"Invalid rpcEndpoint URI: $rpcEndpoint"} 22 | } 23 | 24 | override fun toString(): String { 25 | return "ConnectionId(rpcEndpoint=$rpcEndpoint, chainId=$chainId, isHttp=$isHttp, isWebsocket=$isWebsocket)" 26 | } 27 | } -------------------------------------------------------------------------------- /src/adhara/interop-service/corda-decoder/src/main/java/io/adhara/poc/amqp/codec/ByteElement.java: -------------------------------------------------------------------------------- 1 | package io.adhara.poc.amqp.codec; 2 | 3 | import java.nio.ByteBuffer; 4 | 5 | class ByteElement extends AtomicElement { 6 | 7 | private final byte _value; 8 | 9 | ByteElement(Element parent, Element prev, byte b) { 10 | super(parent, prev); 11 | _value = b; 12 | } 13 | 14 | @Override 15 | public int size() { 16 | return isElementOfArray() ? 1 : 2; 17 | } 18 | 19 | @Override 20 | public Byte getValue() { 21 | return _value; 22 | } 23 | 24 | @Override 25 | public Data.DataType getDataType() { 26 | return Data.DataType.BYTE; 27 | } 28 | 29 | @Override 30 | public int encode(ByteBuffer b) { 31 | if (isElementOfArray()) { 32 | if (b.hasRemaining()) { 33 | b.put(_value); 34 | return 1; 35 | } 36 | } else { 37 | if (b.remaining() >= 2) { 38 | b.put((byte) 0x51); 39 | b.put(_value); 40 | return 2; 41 | } 42 | } 43 | return 0; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/r3/atomic-swap/evm/hardhat.config.js: -------------------------------------------------------------------------------- 1 | require("@nomiclabs/hardhat-waffle"); 2 | require("@nomicfoundation/hardhat-foundry"); 3 | 4 | task("accounts", "Prints the list of accounts", async (taskArgs, hre) => { 5 | const accounts = await hre.ethers.getSigners(); 6 | 7 | for (const account of accounts) { 8 | console.log(account.address); 9 | } 10 | }); 11 | 12 | /** 13 | * @type import('hardhat/config').HardhatUserConfig 14 | */ 15 | module.exports = { 16 | solidity: "0.8.20", 17 | optimizer: {enabled: true}, 18 | networks: { 19 | hardhat: { 20 | // mining: { 21 | // mempool: { 22 | // order: "fifo", 23 | // }, 24 | // auto: false, 25 | // interval: 1000, 26 | // }, 27 | chainId: 1337, 28 | }, 29 | }, 30 | paths: { 31 | sources: "./src", 32 | tests: "./test", 33 | cache: "./build/cache", 34 | artifacts: "./build/out" 35 | }, 36 | foundry: { 37 | remappings: "./remappings.txt", 38 | }, 39 | }; 40 | -------------------------------------------------------------------------------- /src/adhara/interop-service/crosschainInterop/api/admin/services/cordaRegisteredFunctionService.js: -------------------------------------------------------------------------------- 1 | function init(config, crosschainApplicationSDK){ 2 | const service = { 3 | getRegisteredFunction: async function getRegisteredFunction(networkId, remoteNetworkId, functionSignature, index){ 4 | return await crosschainApplicationSDK.getCordaParameterHandler(networkId, remoteNetworkId, functionSignature, index) 5 | }, 6 | postRegisteredFunction: async function postRegisteredFunction(networkId, remoteNetworkId, functionSignature, body){ 7 | return await crosschainApplicationSDK.setCordaParameterHandlers(networkId, remoteNetworkId, functionSignature, body) 8 | }, 9 | deleteRegisteredFunction: async function deleteRegisteredFunction(networkId, remoteNetworkId, functionSignature){ 10 | return await crosschainApplicationSDK.removeCordaParameterHandlers(networkId, remoteNetworkId, functionSignature) 11 | } 12 | } 13 | 14 | return service 15 | } 16 | 17 | module.exports = init 18 | -------------------------------------------------------------------------------- /.github/workflows/gradle.yml: -------------------------------------------------------------------------------- 1 | name: CI - R3 Corda/EVM onnly 2 | 3 | on: 4 | push: 5 | paths: 6 | - 'src/r3/atomic-swap/**' 7 | pull_request: 8 | paths: 9 | - 'src/r3/atomic-swap/**' 10 | 11 | permissions: 12 | contents: read 13 | 14 | jobs: 15 | build: 16 | 17 | runs-on: ubuntu-latest 18 | 19 | steps: 20 | - uses: actions/checkout@v3 21 | with: 22 | submodules: recursive 23 | 24 | - name: Run R3 harmonia testnet 25 | run: | 26 | docker run --platform linux/amd64 -d -p 8545:8545 edoardoierina/r3-harmonia-testnet:latest 27 | 28 | - name: Set up JDK 8 29 | uses: actions/setup-java@v3 30 | with: 31 | java-version: '8' 32 | distribution: 'temurin' 33 | 34 | - name: Build with Gradle 35 | uses: gradle/gradle-build-action@bd5760595778326ba7f1441bcf7e88b49de61a25 # v2.6.0 36 | with: 37 | arguments: clean test --continue 38 | build-root-directory: 'src/r3/atomic-swap/corda' 39 | -------------------------------------------------------------------------------- /src/adhara/interop-service/corda-decoder/src/main/java/io/adhara/poc/amqp/codec/ShortElement.java: -------------------------------------------------------------------------------- 1 | package io.adhara.poc.amqp.codec; 2 | 3 | import java.nio.ByteBuffer; 4 | 5 | class ShortElement extends AtomicElement { 6 | 7 | private final short _value; 8 | 9 | ShortElement(Element parent, Element prev, short s) { 10 | super(parent, prev); 11 | _value = s; 12 | } 13 | 14 | @Override 15 | public int size() { 16 | return isElementOfArray() ? 2 : 3; 17 | } 18 | 19 | @Override 20 | public Short getValue() { 21 | return _value; 22 | } 23 | 24 | @Override 25 | public Data.DataType getDataType() { 26 | return Data.DataType.SHORT; 27 | } 28 | 29 | @Override 30 | public int encode(ByteBuffer b) { 31 | if (isElementOfArray()) { 32 | if (b.remaining() >= 2) { 33 | b.putShort(_value); 34 | return 2; 35 | } 36 | } else { 37 | if (b.remaining() >= 3) { 38 | b.put((byte) 0x61); 39 | b.putShort(_value); 40 | return 3; 41 | } 42 | } 43 | return 0; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/adhara/interop-service/corda-decoder/src/main/java/io/adhara/poc/ledger/PartialTree.java: -------------------------------------------------------------------------------- 1 | package io.adhara.poc.ledger; 2 | 3 | import lombok.Data; 4 | 5 | @Data 6 | public class PartialTree { 7 | private SecureHash hash; 8 | private PartialTree left; 9 | private PartialTree right; 10 | private String hashAlgorithm; 11 | private Type type; 12 | 13 | private enum Type { 14 | INCLUDED, 15 | LEAF, 16 | NODE, 17 | } 18 | 19 | public PartialTree(SecureHash hash, boolean isLeaf) { 20 | this.hash = hash; 21 | this.type = isLeaf ? Type.LEAF : Type.INCLUDED; 22 | } 23 | 24 | public PartialTree(PartialTree left, PartialTree right, String hashAlgorithm) { 25 | this.left = left; 26 | this.right = right; 27 | this.hashAlgorithm = hashAlgorithm; 28 | this.type = Type.NODE; 29 | } 30 | 31 | public boolean isLeaf() { return type == Type.LEAF; } 32 | public boolean isIncluded() { return type == Type.INCLUDED; } 33 | public boolean isNode() { return type == Type.NODE; } 34 | } -------------------------------------------------------------------------------- /src/adhara/interop-service/besu/services/config.toml: -------------------------------------------------------------------------------- 1 | # Network 2 | # bootnodes=["enode://001@123:4567", "enode://002@123:4567", "enode://003@123:4567"] 3 | 4 | p2p-host="127.0.0.1" 5 | p2p-port=1234 6 | max-peers=42 7 | 8 | rpc-http-enabled=true 9 | rpc-http-api=["ETH","NET","IBFT","DEBUG","WEB3","TXPOOL","ADMIN"] 10 | 11 | host-whitelist=["*"] 12 | rpc-http-cors-origins=["all"] 13 | 14 | rpc-http-host="0.0.0.0" 15 | rpc-http-port=8545 16 | 17 | rpc-ws-enabled=false 18 | rpc-ws-host="0.0.0.0" 19 | rpc-ws-port=8546 20 | 21 | # Chain 22 | genesis-file="./genesis.json" # Path to the custom genesis file 23 | 24 | # Mining 25 | miner-enabled=true 26 | miner-coinbase="0xfe3b557e8fb62b89f4916b721be55ceb828dbd73" 27 | 28 | 29 | min-gas-price="0" 30 | 31 | revert-reason-enabled=true 32 | 33 | 34 | metrics-category=[ "ETHEREUM", "BLOCKCHAIN","EXECUTORS","JVM","NETWORK","PEERS","PROCESS","KVSTORE_ROCKSDB","KVSTORE_ROCKSDB_STATS","RPC","SYNCHRONIZER", "TRANSACTION_POOL" ] 35 | 36 | metrics-enabled=true 37 | metrics-host="0.0.0.0" 38 | -------------------------------------------------------------------------------- /src/r3/atomic-swap/corda/evm-interop-contracts/src/main/kotlin/com/r3/corda/evminterop/states/swap/LockState.kt: -------------------------------------------------------------------------------- 1 | package com.r3.corda.evminterop.states.swap 2 | 3 | import com.r3.corda.evminterop.IUnlockEventEncoder 4 | import com.r3.corda.evminterop.contracts.swap.LockStateContract 5 | import net.corda.core.contracts.BelongsToContract 6 | import net.corda.core.contracts.ContractState 7 | import net.corda.core.identity.AbstractParty 8 | import java.security.PublicKey 9 | 10 | /** 11 | * The [LockState] data structure allows to define the Unlock/Revert expectations 12 | */ 13 | @BelongsToContract(LockStateContract::class) 14 | class LockState(val assetSender: PublicKey, 15 | val assetRecipient: PublicKey, 16 | val notary: PublicKey, 17 | val approvedValidators: List, 18 | val signaturesThreshold: Int, 19 | val unlockEvent: IUnlockEventEncoder, 20 | override val participants: List = emptyList()) : ContractState 21 | -------------------------------------------------------------------------------- /src/adhara/interop-service/corda-decoder/src/main/java/io/adhara/poc/amqp/codec/AbstractPrimitiveTypeEncoding.java: -------------------------------------------------------------------------------- 1 | package io.adhara.poc.amqp.codec; 2 | 3 | abstract class AbstractPrimitiveTypeEncoding implements PrimitiveTypeEncoding { 4 | private final EncoderImpl _encoder; 5 | private final DecoderImpl _decoder; 6 | 7 | AbstractPrimitiveTypeEncoding(final EncoderImpl encoder, final DecoderImpl decoder) { 8 | _encoder = encoder; 9 | _decoder = decoder; 10 | } 11 | 12 | public final void writeConstructor() { 13 | _encoder.writeRaw(getEncodingCode()); 14 | } 15 | 16 | public int getConstructorSize() { 17 | return 1; 18 | } 19 | 20 | public abstract byte getEncodingCode(); 21 | 22 | protected EncoderImpl getEncoder() { 23 | return _encoder; 24 | } 25 | 26 | public Class getTypeClass() { 27 | return getType().getTypeClass(); 28 | } 29 | 30 | protected DecoderImpl getDecoder() { 31 | return _decoder; 32 | } 33 | 34 | 35 | public boolean encodesJavaPrimitive() { 36 | return false; 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/adhara/interop-service/corda-decoder/src/main/java/io/adhara/poc/amqp/codec/Decimal32Element.java: -------------------------------------------------------------------------------- 1 | package io.adhara.poc.amqp.codec; 2 | 3 | import io.adhara.poc.amqp.types.Decimal32; 4 | 5 | import java.nio.ByteBuffer; 6 | 7 | class Decimal32Element extends AtomicElement { 8 | 9 | private final Decimal32 _value; 10 | 11 | Decimal32Element(Element parent, Element prev, Decimal32 d) { 12 | super(parent, prev); 13 | _value = d; 14 | } 15 | 16 | @Override 17 | public int size() { 18 | return isElementOfArray() ? 4 : 5; 19 | } 20 | 21 | @Override 22 | public Decimal32 getValue() { 23 | return _value; 24 | } 25 | 26 | @Override 27 | public Data.DataType getDataType() { 28 | return Data.DataType.DECIMAL32; 29 | } 30 | 31 | @Override 32 | public int encode(ByteBuffer b) { 33 | int size = size(); 34 | if (b.remaining() >= size) { 35 | if (size == 5) { 36 | b.put((byte) 0x74); 37 | } 38 | b.putInt(_value.getBits()); 39 | return size; 40 | } else { 41 | return 0; 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/adhara/interop-service/corda-decoder/src/main/java/io/adhara/poc/amqp/codec/Decimal64Element.java: -------------------------------------------------------------------------------- 1 | package io.adhara.poc.amqp.codec; 2 | 3 | import io.adhara.poc.amqp.types.Decimal64; 4 | 5 | import java.nio.ByteBuffer; 6 | 7 | class Decimal64Element extends AtomicElement { 8 | 9 | private final Decimal64 _value; 10 | 11 | Decimal64Element(Element parent, Element prev, Decimal64 d) { 12 | super(parent, prev); 13 | _value = d; 14 | } 15 | 16 | @Override 17 | public int size() { 18 | return isElementOfArray() ? 8 : 9; 19 | } 20 | 21 | @Override 22 | public Decimal64 getValue() { 23 | return _value; 24 | } 25 | 26 | @Override 27 | public Data.DataType getDataType() { 28 | return Data.DataType.DECIMAL64; 29 | } 30 | 31 | @Override 32 | public int encode(ByteBuffer b) { 33 | int size = size(); 34 | if (b.remaining() >= size) { 35 | if (size == 9) { 36 | b.put((byte) 0x84); 37 | } 38 | b.putLong(_value.getBits()); 39 | return size; 40 | } else { 41 | return 0; 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/adhara/interop-service/crosschainInterop/src/CrosschainApplicationSDK/helpers.js: -------------------------------------------------------------------------------- 1 | 2 | function init(config, dependencies) { 3 | 4 | const logger = dependencies.logger 5 | const web3Store = dependencies.web3Store 6 | 7 | async function getOperationIdFromTradeId(networkName, tradeId, fromAccount, toAccount) { 8 | const web3 = web3Store[networkName] 9 | const operationId = web3.utils.soliditySha3({ 10 | type: 'string', 11 | value: tradeId.toString() 12 | }, fromAccount, toAccount).substring(2) 13 | logger.log('silly', `Calculating operationId from tradeId: [${tradeId}], fromAccount: [${fromAccount}], toAccount [${toAccount}] => operationId: [${operationId}]`) 14 | return operationId 15 | } 16 | 17 | async function getCurrentBlock(networkName) { 18 | const latestBlock = await web3Store[networkName].eth.getBlock('latest') 19 | return latestBlock.number 20 | } 21 | 22 | return { 23 | getOperationIdFromTradeId, 24 | getCurrentBlock 25 | } 26 | } 27 | 28 | module.exports = init 29 | 30 | -------------------------------------------------------------------------------- /src/adhara/interop-service/corda-decoder/src/main/java/io/adhara/poc/amqp/codec/UUIDElement.java: -------------------------------------------------------------------------------- 1 | package io.adhara.poc.amqp.codec; 2 | 3 | import java.nio.ByteBuffer; 4 | import java.util.UUID; 5 | 6 | class UUIDElement extends AtomicElement { 7 | 8 | private final UUID _value; 9 | 10 | UUIDElement(Element parent, Element prev, UUID u) { 11 | super(parent, prev); 12 | _value = u; 13 | } 14 | 15 | @Override 16 | public int size() { 17 | return isElementOfArray() ? 16 : 17; 18 | } 19 | 20 | @Override 21 | public UUID getValue() { 22 | return _value; 23 | } 24 | 25 | @Override 26 | public Data.DataType getDataType() { 27 | return Data.DataType.UUID; 28 | } 29 | 30 | @Override 31 | public int encode(ByteBuffer b) { 32 | int size = size(); 33 | if (b.remaining() >= size) { 34 | if (size == 17) { 35 | b.put((byte) 0x98); 36 | } 37 | b.putLong(_value.getMostSignificantBits()); 38 | b.putLong(_value.getLeastSignificantBits()); 39 | return size; 40 | } else { 41 | return 0; 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/adhara/interop-service/crosschainInterop/api/admin/paths/validators.js: -------------------------------------------------------------------------------- 1 | module.exports = function (app, validatorService) { 2 | 3 | app.get('/validators', async (req, res, next) => { 4 | /* #swagger.tags = ['Validators'] 5 | #swagger.summary = 'Fetch list of validators.' */ 6 | // #swagger.operationId = "getValidators" 7 | /* #swagger.parameters['obj'] = { 8 | in: 'query', 9 | name: 'blockHash', 10 | required: false, 11 | type: 'string' 12 | } 13 | */ 14 | try { 15 | /* #swagger.responses[200] = { 16 | schema: { "$ref": "#/definitions/Validators" }, description: "Fetched list of validators." } 17 | */ 18 | res.status(200).json(await validatorService.getValidators(req.query.blockHash)); 19 | } catch (error) { 20 | console.log(error) 21 | // #swagger.responses[500] = { description: "An error occurred." } 22 | res.status(500).json("Server error, could not get validators, please contact system admin") 23 | } 24 | }) 25 | 26 | } 27 | 28 | -------------------------------------------------------------------------------- /src/adhara/interop-service/crosschainInterop/Makefile: -------------------------------------------------------------------------------- 1 | PROJECT ?= crosscha-interop 2 | TAG ?= local 3 | DOCKER_REPO ?= adhara-docker.jfrog.io/adharaprojects 4 | 5 | build: 6 | docker build -t ${DOCKER_REPO}/${PROJECT}:${TAG} \ 7 | --build-arg ARTIFACTORY_USER=${ARTIFACTORY_USER} \ 8 | --build-arg ARTIFACTORY_PASSWORD=${ARTIFACTORY_PASSWORD} \ 9 | -f ./crosschainInterop/Dockerfile \ 10 | ./crosschainInterop 11 | 12 | publish: build 13 | docker push ${DOCKER_REPO}/${PROJECT}:${TAG} 14 | 15 | scan: 16 | @echo "Scanning docker image" 17 | trivy image --exit-code 0 --severity "UNKNOWN,LOW" --no-progress ${DOCKER_REPO}/${PROJECT}:${TAG} 18 | trivy image --exit-code 0 --severity "MEDIUM,HIGH,CRITICAL" --no-progress ${DOCKER_REPO}/${PROJECT}:${TAG} 19 | 20 | 21 | .PHONY: setup 22 | setup: 23 | @npm ci 24 | 25 | .PHONY: clean 26 | clean: 27 | @rm -rf build 28 | 29 | .PHONY: compile 30 | compile: 31 | @npx hardhat compile 32 | 33 | .PHONY: test 34 | test: 35 | @npx hardhat specific-test --sources contracts/libraries --tests test/ --show-stack-traces 36 | -------------------------------------------------------------------------------- /src/adhara/interop-service/crosschainInterop/contracts/test/SECP256K1Verify.sol: -------------------------------------------------------------------------------- 1 | /* 2 | IT IS UNDERSTOOD THAT THE PROOF OF CONCEPT SOFTWARE, DOCUMENTATION, AND ANY UPDATES MAY CONTAIN ERRORS AND ARE PROVIDED FOR LIMITED EVALUATION ONLY. THE PROOF OF CONCEPT SOFTWARE, THE DOCUMENTATION, 3 | AND ANY UPDATES ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, WHETHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE. 4 | */ 5 | 6 | // SPDX-License-Identifier: MIT 7 | pragma solidity ^0.8.13; 8 | 9 | import "contracts/libraries/SECP256K1.sol"; 10 | 11 | contract SECP256K1Verify { 12 | 13 | function verify( 14 | bytes32 k, 15 | bytes32 r, 16 | bytes32 s, 17 | bytes1 v, 18 | bytes memory m 19 | ) public view returns (bool) { 20 | return SECP256K1.verify(k, r, s, v, m); 21 | } 22 | 23 | function verifySignature( 24 | uint[2] memory k, 25 | uint[2] memory rs, 26 | bytes memory m 27 | ) public view returns (bool) { 28 | bytes32 messageHash = sha256(m); 29 | return SECP256K1.verifySignature(messageHash, rs, k); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /docs/adhara/contents.md: -------------------------------------------------------------------------------- 1 | # Summary of documents contributed by Adhara 2 | The following documents have been contributed by Adhara 3 | 4 | - [Interop principles](interop_principles.md) Some basic interop principles that have been agreed by a number of banks who are invested in this emerging ecosystem. 5 | - [Bank Side patterns](bank_side_patterns.md) This is a document that explores the impact that standardising, a few generic interfaces, can have on the adoptability by banks, to be able to connect to and manage the new emerging platforms. 6 | - [Atomic Settlement](atomic_settlement.md) A review of the process of ensuring that in a settlement that consists of more than one leg, all the settlement legs succeed or none succeed. 7 | - [Crosschain Protocols](crosschain_protocols) Extending the concepts in the above document, this document looks at different crosschain protocols that can enable atomic settlement. 8 | - [Crosschain Interoperability](crosschain_interoperability.md) Technical design and protocol level discussions regarding implementation of crosschain PvP and DvP. 9 | 10 | -------------------------------------------------------------------------------- /src/adhara/interop-service/corda-decoder/src/main/java/io/adhara/poc/amqp/codec/AtomicElement.java: -------------------------------------------------------------------------------- 1 | package io.adhara.poc.amqp.codec; 2 | 3 | abstract class AtomicElement extends AbstractElement { 4 | 5 | AtomicElement(Element parent, Element prev) { 6 | super(parent, prev); 7 | } 8 | 9 | @Override 10 | public Element child() { 11 | throw new UnsupportedOperationException(); 12 | } 13 | 14 | @Override 15 | public void setChild(Element elt) { 16 | throw new UnsupportedOperationException(); 17 | } 18 | 19 | 20 | @Override 21 | public boolean canEnter() { 22 | return false; 23 | } 24 | 25 | @Override 26 | public Element checkChild(Element element) { 27 | throw new UnsupportedOperationException(); 28 | } 29 | 30 | @Override 31 | public Element addChild(Element element) { 32 | throw new UnsupportedOperationException(); 33 | } 34 | 35 | @Override 36 | String startSymbol() { 37 | throw new UnsupportedOperationException(); 38 | } 39 | 40 | @Override 41 | String stopSymbol() { 42 | throw new UnsupportedOperationException(); 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /src/adhara/interop-service/corda-decoder/src/main/java/io/adhara/poc/amqp/codec/BooleanElement.java: -------------------------------------------------------------------------------- 1 | package io.adhara.poc.amqp.codec; 2 | 3 | import java.nio.ByteBuffer; 4 | 5 | class BooleanElement extends AtomicElement { 6 | private final boolean _value; 7 | 8 | public BooleanElement(Element parent, Element current, boolean b) { 9 | super(parent, current); 10 | _value = b; 11 | } 12 | 13 | @Override 14 | public int size() { 15 | // in non-array parent then there is a single byte encoding, in an array there is a 1-byte encoding but no 16 | // constructor 17 | return 1; 18 | } 19 | 20 | @Override 21 | public Boolean getValue() { 22 | return _value; 23 | } 24 | 25 | @Override 26 | public Data.DataType getDataType() { 27 | return Data.DataType.BOOL; 28 | } 29 | 30 | @Override 31 | public int encode(ByteBuffer b) { 32 | if (b.hasRemaining()) { 33 | if (isElementOfArray()) { 34 | b.put(_value ? (byte) 1 : (byte) 0); 35 | } else { 36 | b.put(_value ? (byte) 0x41 : (byte) 0x42); 37 | } 38 | return 1; 39 | } 40 | return 0; 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /src/adhara/interop-service/corda-decoder/src/main/java/io/adhara/poc/amqp/codec/Decimal128Element.java: -------------------------------------------------------------------------------- 1 | package io.adhara.poc.amqp.codec; 2 | 3 | import io.adhara.poc.amqp.types.Decimal128; 4 | 5 | import java.nio.ByteBuffer; 6 | 7 | class Decimal128Element extends AtomicElement { 8 | 9 | private final Decimal128 _value; 10 | 11 | Decimal128Element(Element parent, Element prev, Decimal128 d) { 12 | super(parent, prev); 13 | _value = d; 14 | } 15 | 16 | @Override 17 | public int size() { 18 | return isElementOfArray() ? 16 : 17; 19 | } 20 | 21 | @Override 22 | public Decimal128 getValue() { 23 | return _value; 24 | } 25 | 26 | @Override 27 | public Data.DataType getDataType() { 28 | return Data.DataType.DECIMAL128; 29 | } 30 | 31 | @Override 32 | public int encode(ByteBuffer b) { 33 | int size = size(); 34 | if (b.remaining() >= size) { 35 | if (size == 17) { 36 | b.put((byte) 0x94); 37 | } 38 | b.putLong(_value.getMostSignificantBits()); 39 | b.putLong(_value.getLeastSignificantBits()); 40 | return size; 41 | } else { 42 | return 0; 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/adhara/interop-service/crosschainInterop/src/Adapters/EthClient/settlementObligations.js: -------------------------------------------------------------------------------- 1 | 2 | function init(config, dependencies){ 3 | 4 | const logger = dependencies.logger 5 | const assetTokenContract = dependencies.assetTokenContract 6 | 7 | const decimals = 2 8 | 9 | async function createAndMakeHoldPerpetual(networkName, tradeId, fromAccountId, toAccountId, amount, localOperationId) { 10 | let createHoldResponse = await assetTokenContract.createHold(networkName, localOperationId, fromAccountId, toAccountId, amount * Math.pow(10, decimals)) 11 | logger.log('debug', 'Response from asset token contract create hold: '+ JSON.stringify(createHoldResponse, null, 2)) 12 | let makeHoldPerpetualResponse = await assetTokenContract.makeHoldPerpetual(networkName, localOperationId) 13 | logger.log('debug', 'Response from asset token contract make hold perpetual: '+ JSON.stringify(makeHoldPerpetualResponse, null, 2)) 14 | return [createHoldResponse, makeHoldPerpetualResponse] 15 | } 16 | 17 | return { 18 | createAndMakeHoldPerpetual 19 | } 20 | } 21 | 22 | module.exports = init 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/r3/atomic-swap/corda/evm-interop-contracts/src/main/kotlin/com/r3/corda/evminterop/dto/Transaction.kt: -------------------------------------------------------------------------------- 1 | package com.r3.corda.evminterop.dto 2 | 3 | import net.corda.core.serialization.CordaSerializable 4 | import java.math.BigInteger 5 | 6 | /** 7 | * A Corda serializable version of the Web3j's Transaction that acts as a DTO and allows flows to return the 8 | * ethereum transaction object using Corda serialization. 9 | */ 10 | @CordaSerializable 11 | public class Transaction( 12 | val hash: String, 13 | val nonce: BigInteger, 14 | val blockHash: String, 15 | val blockNumber: BigInteger, 16 | val chainId: Long, 17 | val transactionIndex: BigInteger, 18 | val from: String, 19 | val to: String, 20 | val value: BigInteger, 21 | val gasPrice: BigInteger, 22 | val gas: BigInteger, 23 | val input: String, 24 | val raw: String, 25 | val r: String, 26 | val s: String, 27 | val v: Long = 0, // see https://github.com/web3j/web3j/issues/44 28 | val type: String, 29 | val maxFeePerGas: BigInteger, 30 | val maxPriorityFeePerGas: BigInteger 31 | ) { 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/adhara/interop-service/corda-decoder/src/main/java/io/adhara/poc/amqp/codec/UnsignedByteElement.java: -------------------------------------------------------------------------------- 1 | package io.adhara.poc.amqp.codec; 2 | 3 | import io.adhara.poc.amqp.types.UnsignedByte; 4 | 5 | import java.nio.ByteBuffer; 6 | 7 | class UnsignedByteElement extends AtomicElement { 8 | 9 | private final UnsignedByte _value; 10 | 11 | UnsignedByteElement(Element parent, Element prev, UnsignedByte ub) { 12 | super(parent, prev); 13 | _value = ub; 14 | } 15 | 16 | @Override 17 | public int size() { 18 | return isElementOfArray() ? 1 : 2; 19 | } 20 | 21 | @Override 22 | public UnsignedByte getValue() { 23 | return _value; 24 | } 25 | 26 | @Override 27 | public Data.DataType getDataType() { 28 | return Data.DataType.UBYTE; 29 | } 30 | 31 | @Override 32 | public int encode(ByteBuffer b) { 33 | if (isElementOfArray()) { 34 | if (b.hasRemaining()) { 35 | b.put(_value.byteValue()); 36 | return 1; 37 | } 38 | } else { 39 | if (b.remaining() >= 2) { 40 | b.put((byte) 0x50); 41 | b.put(_value.byteValue()); 42 | return 2; 43 | } 44 | } 45 | return 0; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/adhara/interop-service/crosschainInterop/contracts/test/ED25519Verify.sol: -------------------------------------------------------------------------------- 1 | /* 2 | IT IS UNDERSTOOD THAT THE PROOF OF CONCEPT SOFTWARE, DOCUMENTATION, AND ANY UPDATES MAY CONTAIN ERRORS AND ARE PROVIDED FOR LIMITED EVALUATION ONLY. THE PROOF OF CONCEPT SOFTWARE, THE DOCUMENTATION, 3 | AND ANY UPDATES ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, WHETHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE. 4 | */ 5 | 6 | // SPDX-License-Identifier: Apache-2.0 7 | pragma solidity ^0.8.13; 8 | 9 | import "contracts/libraries/ED25519.sol"; 10 | 11 | contract ED25519Verify { 12 | function verify( 13 | bytes32 k, 14 | bytes32 r, 15 | bytes32 s, 16 | bytes memory m 17 | ) public pure returns (bool) { 18 | return ED25519.verify(k, r, s, m); 19 | } 20 | 21 | event Bool(bool, string); 22 | 23 | function verifyWithEvent( 24 | bytes32 k, 25 | bytes32 r, 26 | bytes32 s, 27 | bytes memory m 28 | ) public { 29 | emit Bool(ED25519.verify(k, r, s, m), "Verification result"); 30 | } 31 | 32 | function decode(bytes memory d) public returns (bytes memory) { 33 | return ED25519.decode(d); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/adhara/interop-service/besu/services/genesis-1.json: -------------------------------------------------------------------------------- 1 | { 2 | "config": { 3 | "muirGlacierBlock": 0, 4 | "chainID": 44844, 5 | "contractSizeLimit": 2147483647, 6 | "ibft2": { 7 | "blockperiodseconds": 1, 8 | "epochlength": 30000, 9 | "requesttimeoutseconds": 10, 10 | "blockreward": "0" 11 | } 12 | }, 13 | "nonce": "0x0", 14 | "timestamp": "0x58ee40ba", 15 | "extraData": "0xf83ea00000000000000000000000000000000000000000000000000000000000000000d594ca31306798b41bc81c43094a1e0462890ce7a673808400000000c0", 16 | "gasLimit": "0x5F5E100", 17 | "difficulty": "0x1", 18 | "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365", 19 | "coinbase": "0x0000000000000000000000000000000000000000", 20 | "alloc": { 21 | "627306090abaB3A6e1400e9345bC60c78a8BEf57": { 22 | "privateKey": "c87509a1c067bbde78beb793e6fa76530b6382a4c0241e5e4a9ec0a0f44dc0d3", 23 | "comment": "private key and this comment are ignored. In a real chain, the private key should NOT be stored", 24 | "balance": "6000000000000000000000000000000000000000000000000000000000" 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/adhara/interop-service/besu/services/genesis-2.json: -------------------------------------------------------------------------------- 1 | { 2 | "config": { 3 | "muirGlacierBlock": 0, 4 | "chainID": 55755, 5 | "contractSizeLimit": 2147483647, 6 | "ibft2": { 7 | "blockperiodseconds": 1, 8 | "epochlength": 30000, 9 | "requesttimeoutseconds": 10, 10 | "blockreward": "0" 11 | } 12 | }, 13 | "nonce": "0x0", 14 | "timestamp": "0x58ee40ba", 15 | "extraData": "0xf83ea00000000000000000000000000000000000000000000000000000000000000000d594ca31306798b41bc81c43094a1e0462890ce7a673808400000000c0", 16 | "gasLimit": "0x5F5E100", 17 | "difficulty": "0x1", 18 | "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365", 19 | "coinbase": "0x0000000000000000000000000000000000000000", 20 | "alloc": { 21 | "627306090abaB3A6e1400e9345bC60c78a8BEf57": { 22 | "privateKey": "c87509a1c067bbde78beb793e6fa76530b6382a4c0241e5e4a9ec0a0f44dc0d3", 23 | "comment": "private key and this comment are ignored. In a real chain, the private key should NOT be stored", 24 | "balance": "6000000000000000000000000000000000000000000000000000000000" 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/adhara/interop-service/corda-decoder/src/main/java/io/adhara/poc/amqp/codec/UnsignedShortElement.java: -------------------------------------------------------------------------------- 1 | package io.adhara.poc.amqp.codec; 2 | 3 | import io.adhara.poc.amqp.types.UnsignedShort; 4 | 5 | import java.nio.ByteBuffer; 6 | 7 | class UnsignedShortElement extends AtomicElement { 8 | 9 | private final UnsignedShort _value; 10 | 11 | UnsignedShortElement(Element parent, Element prev, UnsignedShort ub) { 12 | super(parent, prev); 13 | _value = ub; 14 | } 15 | 16 | @Override 17 | public int size() { 18 | return isElementOfArray() ? 2 : 3; 19 | } 20 | 21 | @Override 22 | public UnsignedShort getValue() { 23 | return _value; 24 | } 25 | 26 | @Override 27 | public Data.DataType getDataType() { 28 | return Data.DataType.USHORT; 29 | } 30 | 31 | @Override 32 | public int encode(ByteBuffer b) { 33 | if (isElementOfArray()) { 34 | if (b.remaining() >= 2) { 35 | b.putShort(_value.shortValue()); 36 | return 2; 37 | } 38 | } else { 39 | if (b.remaining() >= 3) { 40 | b.put((byte) 0x60); 41 | b.putShort(_value.shortValue()); 42 | return 3; 43 | } 44 | } 45 | return 0; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/adhara/interop-service/corda-decoder/src/main/java/io/adhara/poc/rest/model/LedgerTransaction.java: -------------------------------------------------------------------------------- 1 | package io.adhara.poc.rest.model; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.NoArgsConstructor; 5 | import lombok.Data; 6 | 7 | @Data 8 | @AllArgsConstructor 9 | @NoArgsConstructor 10 | public class LedgerTransaction { 11 | private String networkId; // Source ledger identification. 12 | private String contractAddress; // Control contract address, or xvp contract address. e.g. 0x12345... 13 | private String functionName; // Destination function in control contract, or xvp function. 14 | private String encodedInfo; // Hex-encoded AMPQ/1.0-encoded signed Corda transaction, e.g. 636F7264610100000080C562000000000001D00... 15 | private String withHiddenAuthParams; // Flag to indicate that authentication parameters should be added to function call data. 16 | private String authNetworkId; // Auth ledger identification. Must be a ledger authorized to call performCallFromRemoteChain. 17 | private String authContractAddress; // Auth contract address, or function call contract address. e.g. 0x12345... 18 | } 19 | -------------------------------------------------------------------------------- /src/r3/atomic-swap/corda/evm-interop-workflows/src/main/kotlin/com/r3/corda/evminterop/services/IERC20.kt: -------------------------------------------------------------------------------- 1 | package com.r3.corda.evminterop.services 2 | 3 | import com.r3.corda.evminterop.dto.TransactionReceipt 4 | import net.corda.core.flows.FlowExternalOperation 5 | import java.math.BigInteger 6 | 7 | interface IERC20 { 8 | // ERC20 Extension 9 | fun name(): FlowExternalOperation 10 | fun symbol(): FlowExternalOperation 11 | fun decimals(): FlowExternalOperation 12 | fun totalSupply(): FlowExternalOperation 13 | 14 | // transactional functions 15 | fun approve(receiverAddress: String, amount: BigInteger): FlowExternalOperation 16 | fun transfer(receiverAddress: String, amount: BigInteger): FlowExternalOperation 17 | fun transferFrom(senderAddress: String, receiverAddress: String, amount: BigInteger): FlowExternalOperation 18 | 19 | // non transactional functions 20 | fun allowance(senderAddress: String, receiverAddress: String): FlowExternalOperation 21 | fun balanceOf(address: String): FlowExternalOperation 22 | } -------------------------------------------------------------------------------- /src/r3/atomic-swap/corda/evm-interop-workflows/src/main/kotlin/com/r3/corda/evminterop/services/BridgeIdentityWithSigner.kt: -------------------------------------------------------------------------------- 1 | package com.r3.corda.evminterop.services 2 | 3 | import com.r3.corda.evminterop.services.internal.RemoteEVMIdentityImpl 4 | import org.web3j.crypto.RawTransaction 5 | import java.net.URI 6 | 7 | data class BridgeIdentityWithSigner( 8 | val signer: AuthorizedSigner, 9 | override val rpcEndpoint: URI, 10 | override val chainId: Long = -1, 11 | override val protocolAddress: String, 12 | override val deployerAddress: String 13 | ) : RemoteEVMIdentityImpl(rpcEndpoint, chainId, protocolAddress, deployerAddress) { 14 | 15 | override fun dispose() { 16 | signer.dispose() 17 | } 18 | 19 | override fun signMessage(rawTransaction: RawTransaction, chainId: Long) : ByteArray { 20 | throw NotImplementedError("Signer protocol not supported") 21 | } 22 | 23 | override fun getAddress(): String { 24 | throw NotImplementedError("Signer protocol not supported") 25 | } 26 | 27 | override fun signData(data: ByteArray) : ByteArray { 28 | throw NotImplementedError("Signer protocol not supported") 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/adhara/interop-service/crosschainInterop/src/CrosschainApplicationSDK/validatorSetManager.js: -------------------------------------------------------------------------------- 1 | const utils = require("../CrosschainSDKUtils"); 2 | 3 | function init(config, dependencies) { 4 | const logger = dependencies.logger 5 | 6 | async function getValidators(networkId) { 7 | const networkName = config.networkIdToNetworkName[networkId] 8 | if (!config[networkName]) { 9 | return Promise.reject(Error('No configuration found for ' + networkName + ', unable to set validators')) 10 | } 11 | if (config[networkName].type !== 'ethereum') { 12 | return Promise.reject(Error('Only possible to set validators on ethereum chains')) 13 | } 14 | const context = config[networkName].context.admin 15 | 16 | let validators = await utils.call(context, config[networkName].contracts.validatorSetManager.path, 'getValidators', []) 17 | 18 | if (!validators) { 19 | return Promise.reject(Error('Failed to retrieve validator set from validator set manager')) 20 | } 21 | logger.log('debug', 'Retrieved validators: ' + JSON.stringify(validators)) 22 | return validators 23 | } 24 | 25 | return { 26 | getValidators 27 | } 28 | } 29 | 30 | module.exports = init 31 | -------------------------------------------------------------------------------- /src/adhara/interop-service/crosschainInterop/contracts/test/SECP256R1Verify.sol: -------------------------------------------------------------------------------- 1 | /* 2 | IT IS UNDERSTOOD THAT THE PROOF OF CONCEPT SOFTWARE, DOCUMENTATION, AND ANY UPDATES MAY CONTAIN ERRORS AND ARE PROVIDED FOR LIMITED EVALUATION ONLY. THE PROOF OF CONCEPT SOFTWARE, THE DOCUMENTATION, 3 | AND ANY UPDATES ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, WHETHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE. 4 | */ 5 | 6 | // SPDX-License-Identifier: MIT 7 | pragma solidity ^0.8.13; 8 | 9 | import "contracts/libraries/SECP256R1.sol"; 10 | 11 | contract SECP256R1Verify { 12 | 13 | event Bytes(bytes, string); 14 | event Bytes32(bytes32, string); 15 | event UInt256(uint256, string); 16 | event String(string, string); 17 | 18 | function verify( 19 | bytes32 k, 20 | bytes32 r, 21 | bytes32 s, 22 | bytes1 v, 23 | bytes memory m 24 | ) public view returns (bool) { 25 | return SECP256R1.verify(k, r, s, v, m); 26 | } 27 | 28 | function verifySignature( 29 | uint[2] memory k, 30 | uint[2] memory rs, 31 | bytes memory m 32 | ) public view returns (bool) { 33 | bytes32 messageHash = sha256(m); 34 | return SECP256R1.verifySignature(messageHash, rs, k); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/adhara/interop-service/crosschainInterop/contracts/test/MerkleVerify.sol: -------------------------------------------------------------------------------- 1 | /* 2 | IT IS UNDERSTOOD THAT THE PROOF OF CONCEPT SOFTWARE, DOCUMENTATION, AND ANY UPDATES MAY CONTAIN ERRORS AND ARE PROVIDED FOR LIMITED EVALUATION ONLY. THE PROOF OF CONCEPT SOFTWARE, THE DOCUMENTATION, 3 | AND ANY UPDATES ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, WHETHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE. 4 | */ 5 | 6 | // SPDX-License-Identifier: Apache-2.0 7 | pragma solidity ^0.8.13; 8 | 9 | import "contracts/libraries/Merkle.sol"; 10 | 11 | contract MerkleVerify { 12 | 13 | function getRoot(bytes32[] memory data) public pure returns (bytes32) { 14 | return Merkle.getRoot(data); 15 | } 16 | 17 | function getProof(bytes32[] memory data, uint256 index) public pure returns (bytes32[] memory) { 18 | return Merkle.getProof(data, index); 19 | } 20 | 21 | function verifyProof(bytes32 root, bytes32[] memory proof, bytes32 value) public pure returns (bool) { 22 | return Merkle.verifyProof(root, proof, value); 23 | } 24 | 25 | function padWithZeros(bytes32[] memory values, bool singleLeaf) public pure returns (bytes32[] memory) { 26 | return Merkle.padWithZeros(values, singleLeaf); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/adhara/interop-service/crosschainInterop/test/base64Verify.js: -------------------------------------------------------------------------------- 1 | const Base64Verify = artifacts.require('Base64Verify'); 2 | 3 | contract('Base64', async (accounts) => { 4 | let instance = null; 5 | 6 | beforeEach(async () => { 7 | instance = await Base64Verify.new(); 8 | }); 9 | 10 | for (const { title, input, expected } of [ 11 | { title: 'should be able to convert to base64 encoded string with double padding', input: 'test', expected: 'dGVzdA==' }, 12 | { title: 'should be able to convert to base64 encoded string with single padding', input: 'test1', expected: 'dGVzdDE=' }, 13 | { title: 'should be able to convert to base64 encoded string without padding', input: 'test12', expected: 'dGVzdDEy' }, 14 | { title: 'should be able to convert to base64 encoded string (/ case)', input: 'où', expected: 'b/k=' }, 15 | { title: 'should be able to convert to base64 encoded string (+ case)', input: 'zs~1t8', expected: 'enN+MXQ4' }, 16 | { title: 'should be able to convert empty bytes', input: '', expected: '' }, 17 | ]) { 18 | it(title, async function () { 19 | const buffer = Buffer.from(input, 'ascii'); 20 | assert.equal(await instance.encode(buffer), expected); 21 | }); 22 | } 23 | }); 24 | -------------------------------------------------------------------------------- /src/r3/atomic-swap/corda/evm-interop-contracts/src/main/kotlin/com/r3/corda/evminterop/dto/Block.kt: -------------------------------------------------------------------------------- 1 | package com.r3.corda.evminterop.dto 2 | 3 | import net.corda.core.serialization.CordaSerializable 4 | import java.math.BigInteger 5 | 6 | /** 7 | * A Corda serializable version of the Web3j's Block that acts as a DTO and allows flows to return the 8 | * ethereum Block object using Corda serialization. 9 | */ 10 | @CordaSerializable 11 | public class Block( 12 | val number: BigInteger, 13 | val hash: String, 14 | val parentHash: String, 15 | val nonce: BigInteger, 16 | val sha3Uncles: String, 17 | val logsBloom: String, 18 | val transactionsRoot: String, 19 | val stateRoot: String, 20 | val receiptsRoot: String, 21 | //val author: String, 22 | val miner: String, 23 | val mixHash: String, 24 | val difficulty: BigInteger, 25 | val totalDifficulty: BigInteger, 26 | val extraData: String, 27 | val size: BigInteger, 28 | val gasLimit: BigInteger, 29 | val gasUsed: BigInteger, 30 | val timestamp: BigInteger, 31 | val transactions: List, 32 | val uncles: List, 33 | //val sealFields: List, 34 | val baseFeePerGas: BigInteger 35 | ) { 36 | 37 | } 38 | -------------------------------------------------------------------------------- /src/adhara/interop-service/corda-decoder/src/main/java/io/adhara/poc/amqp/codec/DynamicTypeConstructor.java: -------------------------------------------------------------------------------- 1 | package io.adhara.poc.amqp.codec; 2 | 3 | public class DynamicTypeConstructor implements TypeConstructor { 4 | private final DescribedTypeConstructor _describedTypeConstructor; 5 | private final TypeConstructor _underlyingEncoding; 6 | 7 | public DynamicTypeConstructor(final DescribedTypeConstructor dtc, 8 | final TypeConstructor underlyingEncoding) { 9 | _describedTypeConstructor = dtc; 10 | _underlyingEncoding = underlyingEncoding; 11 | } 12 | 13 | public Object readValue() { 14 | try { 15 | return _describedTypeConstructor.newInstance(_underlyingEncoding.readValue()); 16 | } catch (NullPointerException npe) { 17 | throw new DecodeException("Unexpected null value - mandatory field not set? (" + npe.getMessage() + ")", npe); 18 | } catch (ClassCastException cce) { 19 | throw new DecodeException("Incorrect type used", cce); 20 | } 21 | } 22 | 23 | public boolean encodesJavaPrimitive() { 24 | return false; 25 | } 26 | 27 | public void skipValue() { 28 | _underlyingEncoding.skipValue(); 29 | } 30 | 31 | public Class getTypeClass() { 32 | return _describedTypeConstructor.getTypeClass(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/r3/atomic-swap/corda/samples/atomic-swap/swap-workflows/src/main/kotlin/com/interop/flows/SignDraftTransactionByIDFlow.kt: -------------------------------------------------------------------------------- 1 | package com.interop.flows 2 | 3 | import co.paralleluniverse.fibers.Suspendable 4 | import com.r3.corda.evminterop.services.swap.DraftTxService 5 | import com.r3.corda.evminterop.workflows.swap.SignDraftTransactionFlow 6 | import net.corda.core.crypto.SecureHash 7 | import net.corda.core.flows.FlowLogic 8 | import net.corda.core.flows.InitiatingFlow 9 | import net.corda.core.flows.StartableByRPC 10 | import net.corda.core.transactions.SignedTransaction 11 | 12 | /** 13 | * Initiating flow which takes a draft transaction ID and attempts to sign and notarize it. 14 | */ 15 | @StartableByRPC 16 | @InitiatingFlow 17 | class SignDraftTransactionByIDFlow(private val transactionId: SecureHash) : FlowLogic() { 18 | 19 | @Suspendable 20 | override fun call(): SignedTransaction { 21 | 22 | // REVIEW: should either mark as signed, or drop it 23 | val wireTransaction = serviceHub.cordaService(DraftTxService::class.java).getDraftTx(transactionId) 24 | ?: throw IllegalArgumentException("Draft Transaction $transactionId not found"); 25 | 26 | return subFlow(SignDraftTransactionFlow(wireTransaction)) 27 | } 28 | } -------------------------------------------------------------------------------- /src/adhara/interop-service/crosschainInterop/api/app/services/settlementInstructionService.js: -------------------------------------------------------------------------------- 1 | function init(config, crosschainApplicationSDK){ 2 | const settlementInstructionService = { 3 | getSettlementInstruction: async function getSettlementInstruction(networkId, tradeId, fromAccount, toAccount, operationId){ 4 | return await crosschainApplicationSDK.getSettlementInstruction(networkId, tradeId, fromAccount, toAccount, operationId) 5 | }, 6 | postSettlementInstruction: async function postSettlementInstruction(networkId, body){ 7 | return await crosschainApplicationSDK.submitSettlementInstruction(networkId, body) 8 | }, 9 | deleteSettlementInstruction: async function deleteSettlementInstruction(networkId, tradeId, fromAccount, toAccount, operationId){ 10 | return await crosschainApplicationSDK.deleteSettlementInstruction(networkId, tradeId, fromAccount, toAccount, operationId) 11 | }, 12 | patchSettlementInstruction: async function patchSettlementInstruction(networkId, tradeId, fromAccount, toAccount, body){ 13 | return await crosschainApplicationSDK.patchSettlementInstruction(networkId, tradeId, fromAccount, toAccount, body) 14 | } 15 | } 16 | return settlementInstructionService 17 | } 18 | 19 | module.exports = init 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/adhara/interop-service/cordapp/workflows/src/main/resources/migration/xvp.changelog-v1.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/adhara/interop-service/crosschainInterop/api/app/paths/{networkId}/repoObligations.js: -------------------------------------------------------------------------------- 1 | module.exports = function (app, repoObligationService) { 2 | 3 | app.post('/:networkId/repoObligations', async (req, res, next) => { 4 | /* #swagger.tags = ['RepoObligations'] 5 | #swagger.summary = 'Submit a repo obligation.' */ 6 | // #swagger.operationId = "postRepoObligation" 7 | /* #swagger.parameters['networkId'] = { 8 | in: 'path', 9 | required: true, 10 | type: 'string' 11 | } 12 | */ 13 | /* #swagger.parameters['repoObligation'] = { 14 | in: 'body', 15 | schema: { "$ref": "#/definitions/RepoObligation" } 16 | } 17 | */ 18 | try { 19 | /* #swagger.responses[201] = { 20 | schema: { "$ref": "#/definitions/SettlementObligationResponse" }, description: "Created repo obligation." } 21 | */ 22 | const responseToSend = await repoObligationService.postRepoObligation(req.params.networkId, req.body) 23 | res.status(201).json(responseToSend) 24 | } catch (error) { 25 | console.log(error) 26 | // #swagger.responses[500] = { description: "An error occurred." } 27 | res.status(500).json("Server error, could not create corda notary, please contact system admin") 28 | } 29 | }) 30 | 31 | }; 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /src/adhara/interop-service/crosschainInterop/contracts/test/EthereumVerify.sol: -------------------------------------------------------------------------------- 1 | /* 2 | IT IS UNDERSTOOD THAT THE PROOF OF CONCEPT SOFTWARE, DOCUMENTATION, AND ANY UPDATES MAY CONTAIN ERRORS AND ARE PROVIDED FOR LIMITED EVALUATION ONLY. THE PROOF OF CONCEPT SOFTWARE, THE DOCUMENTATION, 3 | AND ANY UPDATES ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, WHETHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE. 4 | */ 5 | 6 | // SPDX-License-Identifier: Apache-2.0 7 | pragma solidity ^0.8.13; 8 | 9 | import "contracts/libraries/Ethereum.sol"; 10 | 11 | contract EthereumVerify { 12 | 13 | function verifyBFTBlockHeader( 14 | bytes32 blockHash, 15 | bytes memory blockHeader, 16 | bytes memory blockHeaderPreImage 17 | ) public view returns (uint256 blockNumber, bytes32 receiptsRoot) { 18 | return Ethereum.verifyBFTBlockHeader(blockHash, blockHeader, blockHeaderPreImage); 19 | } 20 | 21 | function verifyEVMEvent( 22 | Ethereum.EventData memory eventData, 23 | bytes32 root, 24 | bytes memory witnesses 25 | ) public pure returns (bool) { 26 | return Ethereum.verifyEVMEvent(eventData, root, witnesses); 27 | } 28 | 29 | function compareBlockHeaders( 30 | RLP.RLPItem[] memory header1, 31 | RLP.RLPItem[] memory header2 32 | ) internal view { 33 | Ethereum.compareBlockHeaders(header1, header2); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/r3/atomic-swap/corda/evm-interop-common/src/main/kotlin/com/r3/corda/interop/evm/common/trie/EmptyNode.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023, R3 LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.r3.corda.interop.evm.common.trie 18 | 19 | import org.web3j.rlp.RlpEncoder 20 | import org.web3j.rlp.RlpString 21 | 22 | /** 23 | * Represents an EmptyNode in a Patricia Trie. 24 | * 25 | * This class is a specific type of Node, with its encoded form 26 | * being the RLP (Recursive Length Prefix) encoding of an empty byte array. 27 | */ 28 | class EmptyNode : Node() { 29 | /** 30 | * Returns the RLP-encoded form of the EmptyNode, 31 | * which is an empty byte array encoded in RLP. 32 | */ 33 | override val encoded: ByteArray 34 | get() = RlpEncoder.encode(RlpString.create(ByteArray(0))) 35 | } 36 | 37 | -------------------------------------------------------------------------------- /src/adhara/interop-service/crosschainInterop/contracts/interfaces/ICrosschainVerifier.sol: -------------------------------------------------------------------------------- 1 | /* 2 | IT IS UNDERSTOOD THAT THE PROOF OF CONCEPT SOFTWARE, DOCUMENTATION, AND ANY UPDATES MAY CONTAIN ERRORS AND ARE PROVIDED FOR LIMITED EVALUATION ONLY. THE PROOF OF CONCEPT SOFTWARE, THE DOCUMENTATION, 3 | AND ANY UPDATES ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, WHETHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE. 4 | */ 5 | 6 | pragma solidity ^0.8.13; 7 | 8 | interface ICrosschainVerifier { 9 | 10 | /* 11 | * Decode and verify the event, transaction or state change according to the registered proving scheme for the given source network. 12 | * @param {uint256} networkId The source network identification. 13 | * @param {bytes} encodedInfo The combined encoding of the network identifier, the destination contract's address, the event function signature, and the event data. 14 | * @param {bytes} signatureOrProof The information that a validating implementation can use to determine if the event data, given as part of encodedInfo, is valid. 15 | * @return {bytes} decodedInfo The decoded information that needs to be acted on after verification of it by means of the provided proof, if any. 16 | */ 17 | function decodeAndVerify( 18 | uint256 networkId, 19 | bytes calldata encodedInfo, 20 | bytes calldata signatureOrProof 21 | ) external view returns (bytes memory decodedInfo); 22 | } 23 | -------------------------------------------------------------------------------- /src/adhara/interop-service/cordapp/workflows/src/main/resources/migration/dcr.changelog-v1.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/r3/atomic-swap/corda/evm-interop-workflows/src/main/kotlin/com/r3/corda/evminterop/workflows/swap/ClaimCommitment.kt: -------------------------------------------------------------------------------- 1 | package com.r3.corda.evminterop.workflows.swap 2 | 3 | import co.paralleluniverse.fibers.Suspendable 4 | import com.r3.corda.evminterop.dto.TransactionReceipt 5 | import com.r3.corda.evminterop.services.evmInterop 6 | import net.corda.core.crypto.SecureHash 7 | import net.corda.core.flows.FlowLogic 8 | import net.corda.core.flows.InitiatingFlow 9 | import net.corda.core.flows.StartableByRPC 10 | 11 | /** 12 | * 13 | */ 14 | @StartableByRPC 15 | @InitiatingFlow 16 | class ClaimCommitment( 17 | private val transactionId: SecureHash 18 | ) : FlowLogic() { 19 | 20 | @Suspendable 21 | override fun call(): TransactionReceipt { 22 | 23 | val swapProvider = evmInterop().swapProvider() 24 | 25 | return await(swapProvider.claimCommitment(transactionId.toString())) 26 | } 27 | } 28 | 29 | @StartableByRPC 30 | @InitiatingFlow 31 | class ClaimCommitmentWithSignatures( 32 | private val transactionId: SecureHash, 33 | private val signatures: List 34 | ) : FlowLogic() { 35 | 36 | @Suspendable 37 | override fun call(): TransactionReceipt { 38 | 39 | val swapProvider = evmInterop().swapProvider() 40 | 41 | return await(swapProvider.claimCommitment(transactionId.toString(), signatures)) 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/r3/atomic-swap/evm/script/SwapVault.s.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | /** 4 | * 5 | * Copyright 2023 R3 LLC * 6 | * * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); * 8 | * you may not use this file except in compliance with the License. * 9 | * You may obtain a copy of the License at * 10 | * * 11 | * http://www.apache.org/licenses/LICENSE-2.0 * 12 | * * 13 | * Unless required by applicable law or agreed to in writing, software * 14 | * distributed under the License is distributed on an "AS IS" BASIS, * 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 16 | * See the License for the specific language governing permissions and * 17 | * limitations under the License. * 18 | * 19 | */ 20 | 21 | pragma solidity =0.8.17; 22 | 23 | import "forge-std/Script.sol"; 24 | 25 | contract SwapVaultScript is Script { 26 | function setUp() public {} 27 | 28 | function run() public { 29 | vm.broadcast(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/r3/atomic-swap/corda/evm-interop-contracts/src/main/kotlin/com/r3/corda/evminterop/states/swap/SwapTransactionDetails.kt: -------------------------------------------------------------------------------- 1 | package com.r3.corda.evminterop.states.swap 2 | 3 | import com.r3.corda.evminterop.EncodedEvent 4 | import com.r3.corda.evminterop.IUnlockEventEncoder 5 | import com.r3.corda.evminterop.SwapVaultEventEncoder 6 | import net.corda.core.contracts.OwnableState 7 | import net.corda.core.contracts.StateAndRef 8 | import net.corda.core.identity.Party 9 | import net.corda.core.serialization.CordaSerializable 10 | 11 | /** 12 | * Simple data structure describing the atomic swap details agreed upon by the involved parties. 13 | * Contains information to identify the sender, receiver, and assets being exchanged on both Corda and EVM networks as 14 | * well as a pool of approved validators/oracles (Corda nodes) which can verify and attest EVM events, and the minimum 15 | * number of validations required for the atomics swap protocol to succeed. 16 | */ 17 | @CordaSerializable 18 | data class SwapTransactionDetails(val senderCordaName: Party, 19 | val receiverCordaName: Party, 20 | val cordaAssetState: StateAndRef, 21 | val approvedCordaValidators: List, 22 | val minimumNumberOfEventValidations: Int, 23 | val unlockEvent: IUnlockEventEncoder 24 | ) -------------------------------------------------------------------------------- /src/r3/atomic-swap/corda/evm-interop-contracts/src/main/kotlin/com/r3/corda/evminterop/dto/DepositStates.kt: -------------------------------------------------------------------------------- 1 | package com.r3.corda.evminterop.dto 2 | 3 | import net.corda.core.serialization.CordaSerializable 4 | import java.math.BigInteger 5 | 6 | /** 7 | * The 6 states a payment can be in are the following: 8 | * 9 | * WAITING - When no deposit done (or no such deposit is expected!) and timeout not expired. 10 | * TIMEOUT - Same conditions as above, but timeout expired. 11 | * REVERTED - When a payment was locked-in earlier but met the revert conditions and was reverted (does not time-out). 12 | * WITHDRAWN - When a payment was locked-in earlier and was withdrawn by the expected recipient (does not time-out). 13 | * In this case, the pre-image of the lock-hash is returned with the status response. 14 | * READY - When a payment is locked-in and ready to be withdrawn (timeout did not expire yet). 15 | * EXPIRED - When a payment is locked-in but it timed-out and therefore can only be reverted. 16 | */ 17 | @CordaSerializable 18 | enum class DepositStates(val value: BigInteger) { 19 | WAITING(0.toBigInteger()), 20 | READY(1.toBigInteger()), 21 | WITHDRAWN(2.toBigInteger()), 22 | EXPIRED(3.toBigInteger()), 23 | REVERTED(4.toBigInteger()), 24 | TIMEOUT(5.toBigInteger()); 25 | companion object { 26 | fun fromBigInteger(value: BigInteger) = DepositStates.values().first { it.value == value } 27 | } 28 | } -------------------------------------------------------------------------------- /src/adhara/interop-service/corda-decoder/src/main/java/io/adhara/poc/amqp/codec/LongElement.java: -------------------------------------------------------------------------------- 1 | package io.adhara.poc.amqp.codec; 2 | 3 | import java.nio.ByteBuffer; 4 | 5 | class LongElement extends AtomicElement { 6 | 7 | private final long _value; 8 | 9 | LongElement(Element parent, Element prev, long l) { 10 | super(parent, prev); 11 | _value = l; 12 | } 13 | 14 | @Override 15 | public int size() { 16 | if (isElementOfArray()) { 17 | final ArrayElement parent = (ArrayElement) parent(); 18 | 19 | if (parent.constructorType() == ArrayElement.SMALL) { 20 | if (-128l <= _value && _value <= 127l) { 21 | return 1; 22 | } else { 23 | parent.setConstructorType(ArrayElement.LARGE); 24 | } 25 | } 26 | 27 | return 8; 28 | 29 | } else { 30 | return (-128l <= _value && _value <= 127l) ? 2 : 9; 31 | } 32 | 33 | } 34 | 35 | @Override 36 | public Long getValue() { 37 | return _value; 38 | } 39 | 40 | @Override 41 | public Data.DataType getDataType() { 42 | return Data.DataType.LONG; 43 | } 44 | 45 | @Override 46 | public int encode(ByteBuffer b) { 47 | int size = size(); 48 | if (size > b.remaining()) { 49 | return 0; 50 | } 51 | switch (size) { 52 | case 2: 53 | b.put((byte) 0x55); 54 | case 1: 55 | b.put((byte) _value); 56 | break; 57 | case 9: 58 | b.put((byte) 0x81); 59 | case 8: 60 | b.putLong(_value); 61 | 62 | } 63 | return size; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/adhara/interop-service/crosschainInterop/api/app/paths/{networkId}/settlementObligations.js: -------------------------------------------------------------------------------- 1 | module.exports = function (app, settlementObligationService) { 2 | 3 | app.post('/:networkId/settlementObligations', async (req, res, next) => { 4 | /* #swagger.tags = ['SettlementObligations'] 5 | #swagger.summary = 'Submit a settlement obligation.' */ 6 | // #swagger.operationId = "postSettlementObligation" 7 | // #swagger.consumes = ["application/json"] 8 | /* #swagger.parameters['networkId'] = { 9 | in: 'path', 10 | required: true, 11 | type: 'string' 12 | } 13 | */ 14 | /* #swagger.parameters['settlementObligation'] = { 15 | in: 'body', 16 | schema: { "$ref": "#/definitions/SettlementObligation" } 17 | } 18 | */ 19 | try { 20 | /* #swagger.responses[201] = { 21 | schema: { "$ref": "#/definitions/SettlementObligationResponse" }, description: "Created settlement instruction." } 22 | */ 23 | const responseToSend = await settlementObligationService.postSettlementObligation(req.params.networkId, req.body) 24 | res.status(201).json(responseToSend) 25 | } catch (error) { 26 | console.log(error) 27 | // #swagger.responses[500] = { description: "An error occurred." } 28 | res.status(500).json("Server error, unable to create settlement obligation, please contact system admin") 29 | } 30 | }) 31 | 32 | }; 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /src/r3/atomic-swap/evm/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'java' 3 | id 'org.web3j' version '4.9.0' 4 | } 5 | node { 6 | version = "20.0.0" 7 | } 8 | 9 | group 'org.web3j' 10 | version '0.2.0' 11 | 12 | sourceCompatibility = 1.8 13 | 14 | repositories { 15 | mavenCentral() 16 | } 17 | 18 | 19 | web3j { 20 | generatedPackageName = "org.web3j.generated.contracts" 21 | generatedFilesBaseDir = "$projectDir/src" 22 | excludedContracts = [] 23 | } 24 | 25 | ext { 26 | web3jVersion = '4.12.1' 27 | } 28 | 29 | def findSolcPath() { 30 | try { 31 | def result = new ByteArrayOutputStream() 32 | exec { 33 | commandLine "which", "solc" 34 | standardOutput = result 35 | } 36 | return result.toString().trim() 37 | } catch (Exception e) { 38 | println "Warning: Could not find solc executable. Defaulting to hardcoded path." 39 | return null 40 | } 41 | } 42 | 43 | solidity { 44 | executable = findSolcPath() ?: "/usr/local/bin/solc" // Fallback if solc isn't found 45 | version = "0.8.17" // NOTE: without version gradle fails with "Cannot invoke method split() on null object" 46 | pathRemappings = [ openzeppelin : "lib/openzeppelin-contracts/contracts" ] 47 | evmVersion = "ISTANBUL" 48 | } 49 | 50 | sourceSets { 51 | main { 52 | solidity { 53 | srcDir { 54 | "src" 55 | } 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/r3/atomic-swap/evm/deploy.js: -------------------------------------------------------------------------------- 1 | const { BigNumber } = require("ethers"); 2 | const hre = require("hardhat"); 3 | 4 | async function main() { 5 | await deployTokens(); 6 | await deployVault(); 7 | } 8 | 9 | async function deployTokens() { 10 | 11 | const tokens = [ 12 | ["Gold Tethered", "GLDT"], 13 | ["Silver Tethered", "SLVT"], 14 | ]; 15 | 16 | for(let i=0; i process.exit(0)) 46 | .catch((error) => { 47 | console.error(error); 48 | process.exit(1); 49 | }); 50 | 51 | -------------------------------------------------------------------------------- /src/r3/atomic-swap/corda/evm-interop-common/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'net.corda.plugins.cordapp' 2 | apply plugin: 'kotlin' 3 | 4 | repositories { 5 | mavenCentral() 6 | maven { url 'https://download.corda.net/maven/corda-releases' } 7 | maven { url 'https://download.corda.net/maven/corda-dependencies' } 8 | } 9 | 10 | cordapp { 11 | targetPlatformVersion corda_platform_version 12 | minimumPlatformVersion corda_platform_version 13 | 14 | workflow { 15 | name "EVM Interop Common Library" 16 | vendor "Corda Open Source" 17 | licence "Apache License, Version 2.0" 18 | versionId 1 19 | } 20 | sealing.enabled false 21 | signing.enabled false 22 | } 23 | 24 | dependencies { 25 | // Kotlin standard library 26 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" 27 | 28 | // Corda dependencies 29 | cordaProvided "$corda_core_release_group:corda-core:$corda_core_release_version" 30 | 31 | // Web3j dependencies 32 | api ("org.web3j:core:$web3jVersion") { transitive = true } 33 | 34 | // test dependencies 35 | testImplementation "org.jetbrains.kotlin:kotlin-test:$kotlin_version" 36 | testImplementation "org.junit.jupiter:junit-jupiter-api:$junit_version" 37 | testImplementation "org.junit.jupiter:junit-jupiter-engine:$junit_version" 38 | testImplementation "org.mockito:mockito-core:$mockitoVersion" 39 | testImplementation "org.mockito:mockito-inline:$mockitoVersion" 40 | } 41 | -------------------------------------------------------------------------------- /src/r3/atomic-swap/corda/evm-interop-workflows/src/main/kotlin/com/r3/corda/evminterop/services/ResponseOperation.kt: -------------------------------------------------------------------------------- 1 | package com.r3.corda.evminterop.services 2 | 3 | import net.corda.core.flows.FlowException 4 | import net.corda.core.flows.FlowExternalOperation 5 | import net.corda.core.utilities.loggerFor 6 | import java.util.* 7 | import java.util.concurrent.CompletableFuture 8 | 9 | /** 10 | * 11 | */ 12 | class ResponseOperation(private val future: CompletableFuture) : 13 | FlowExternalOperation where T : Any { 14 | companion object{ 15 | val log = loggerFor>() 16 | } 17 | 18 | private val operationId = UUID.randomUUID() 19 | 20 | init { 21 | log.info("Op id $operationId created (thread id ${Thread.currentThread().id })") 22 | } 23 | 24 | override fun execute(deduplicationId: String): T { 25 | log.info("Op id $operationId executing (thread id ${Thread.currentThread().id })") 26 | return try { 27 | val result = future.get() 28 | log.info("Op id $operationId executed (thread id ${Thread.currentThread().id })") 29 | result 30 | } catch (e: Exception) { 31 | log.error("Op id $operationId error (thread id ${Thread.currentThread().id }): $e ") 32 | throw FlowException("External API call failed", e) 33 | } finally { 34 | log.info("Op id $operationId exited (thread id ${Thread.currentThread().id })") 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /src/adhara/interop-service/corda-decoder/src/main/java/io/adhara/poc/amqp/codec/IntegerElement.java: -------------------------------------------------------------------------------- 1 | package io.adhara.poc.amqp.codec; 2 | 3 | import java.nio.ByteBuffer; 4 | 5 | class IntegerElement extends AtomicElement { 6 | 7 | private final int _value; 8 | 9 | IntegerElement(Element parent, Element prev, int i) { 10 | super(parent, prev); 11 | _value = i; 12 | } 13 | 14 | @Override 15 | public int size() { 16 | if (isElementOfArray()) { 17 | final ArrayElement parent = (ArrayElement) parent(); 18 | if (parent.constructorType() == ArrayElement.SMALL) { 19 | if (-128 <= _value && _value <= 127) { 20 | return 1; 21 | } else { 22 | parent.setConstructorType(ArrayElement.LARGE); 23 | return 4; 24 | } 25 | } else { 26 | return 4; 27 | } 28 | } else { 29 | return (-128 <= _value && _value <= 127) ? 2 : 5; 30 | } 31 | 32 | } 33 | 34 | @Override 35 | public Integer getValue() { 36 | return _value; 37 | } 38 | 39 | @Override 40 | public Data.DataType getDataType() { 41 | return Data.DataType.INT; 42 | } 43 | 44 | @Override 45 | public int encode(ByteBuffer b) { 46 | int size = size(); 47 | if (size <= b.remaining()) { 48 | switch (size) { 49 | case 2: 50 | b.put((byte) 0x54); 51 | case 1: 52 | b.put((byte) _value); 53 | break; 54 | 55 | case 5: 56 | b.put((byte) 0x71); 57 | case 4: 58 | b.putInt(_value); 59 | 60 | } 61 | 62 | return size; 63 | } 64 | return 0; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/adhara/interop-service/corda-decoder/src/main/java/io/adhara/poc/amqp/codec/DescribedTypeImpl.java: -------------------------------------------------------------------------------- 1 | package io.adhara.poc.amqp.codec; 2 | 3 | import io.adhara.poc.amqp.types.DescribedType; 4 | 5 | class DescribedTypeImpl implements DescribedType { 6 | private final Object _descriptor; 7 | private final Object _described; 8 | 9 | public DescribedTypeImpl(final Object descriptor, final Object described) { 10 | _descriptor = descriptor; 11 | _described = described; 12 | } 13 | 14 | @Override 15 | public Object getDescriptor() { 16 | return _descriptor; 17 | } 18 | 19 | @Override 20 | public Object getDescribed() { 21 | return _described; 22 | } 23 | 24 | @Override 25 | public boolean equals(Object o) { 26 | if (this == o) { 27 | return true; 28 | } 29 | if (o == null || !(o instanceof DescribedType)) { 30 | return false; 31 | } 32 | 33 | DescribedType that = (DescribedType) o; 34 | 35 | if (_described != null ? !_described.equals(that.getDescribed()) : that.getDescribed() != null) { 36 | return false; 37 | } 38 | return _descriptor != null ? _descriptor.equals(that.getDescriptor()) : that.getDescriptor() == null; 39 | } 40 | 41 | @Override 42 | public int hashCode() { 43 | int result = _descriptor != null ? _descriptor.hashCode() : 0; 44 | result = 31 * result + (_described != null ? _described.hashCode() : 0); 45 | return result; 46 | } 47 | 48 | @Override 49 | public String toString() { 50 | return "{" + _descriptor + 51 | ": " + _described + 52 | '}'; 53 | } 54 | } -------------------------------------------------------------------------------- /src/adhara/interop-service/corda-decoder/src/main/java/io/adhara/poc/amqp/types/UnknownDescribedType.java: -------------------------------------------------------------------------------- 1 | package io.adhara.poc.amqp.types; 2 | 3 | public class UnknownDescribedType implements DescribedType { 4 | private final Object _descriptor; 5 | private final Object _described; 6 | 7 | public UnknownDescribedType(final Object descriptor, final Object described) { 8 | _descriptor = descriptor; 9 | _described = described; 10 | } 11 | 12 | @Override 13 | public Object getDescriptor() { 14 | return _descriptor; 15 | } 16 | 17 | @Override 18 | public Object getDescribed() { 19 | return _described; 20 | } 21 | 22 | @Override 23 | public boolean equals(final Object o) { 24 | if (this == o) { 25 | return true; 26 | } 27 | if (o == null || getClass() != o.getClass()) { 28 | return false; 29 | } 30 | 31 | final UnknownDescribedType that = (UnknownDescribedType) o; 32 | 33 | if (_described != null ? !_described.equals(that._described) : that._described != null) { 34 | return false; 35 | } 36 | return _descriptor != null ? _descriptor.equals(that._descriptor) : that._descriptor == null; 37 | } 38 | 39 | @Override 40 | public int hashCode() { 41 | int result = _descriptor != null ? _descriptor.hashCode() : 0; 42 | result = 31 * result + (_described != null ? _described.hashCode() : 0); 43 | return result; 44 | } 45 | 46 | @Override 47 | public String toString() { 48 | return "UnknownDescribedType{" + 49 | "descriptor=" + _descriptor + 50 | ", described=" + _described + 51 | '}'; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/r3/atomic-swap/corda/evm-interop-common/src/main/kotlin/com/r3/corda/interop/evm/common/trie/KeyValueStore.kt: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2023, R3 LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.r3.corda.interop.evm.common.trie 18 | 19 | /** 20 | * An interface for a key-value store. 21 | * 22 | * This store provides methods to retrieve and inspect 23 | * key-value pairings stored within it. 24 | */ 25 | //@CordaSerializable 26 | //interface KeyValueStore { 27 | // 28 | // /** 29 | // * Retrieves the value associated with a given key. 30 | // * 31 | // * @param key The key for which the value is to be retrieved. 32 | // * @return The value associated with the key, or null if the key is not present in the store. 33 | // */ 34 | // fun get(key: ByteArray): ByteArray? 35 | // 36 | // /** 37 | // * Checks whether the store contains any key-value pairings. 38 | // * 39 | // * @return True if the store is empty, false otherwise. 40 | // */ 41 | // fun isEmpty(): Boolean 42 | //} 43 | -------------------------------------------------------------------------------- /src/adhara/interop-service/corda-decoder/src/main/java/io/adhara/poc/amqp/types/Decimal32.java: -------------------------------------------------------------------------------- 1 | package io.adhara.poc.amqp.types; 2 | 3 | import java.math.BigDecimal; 4 | 5 | public final class Decimal32 extends Number { 6 | private final BigDecimal _underlying; 7 | private final int _bits; 8 | 9 | public Decimal32(BigDecimal underlying) { 10 | _underlying = underlying; 11 | _bits = calculateBits(underlying); 12 | } 13 | 14 | public Decimal32(final int bits) { 15 | _bits = bits; 16 | _underlying = calculateBigDecimal(bits); 17 | } 18 | 19 | static int calculateBits(final BigDecimal underlying) { 20 | return 0; //TODO. 21 | } 22 | 23 | static BigDecimal calculateBigDecimal(int bits) { 24 | return BigDecimal.ZERO; // TODO 25 | } 26 | 27 | 28 | @Override 29 | public int intValue() { 30 | return _underlying.intValue(); 31 | } 32 | 33 | @Override 34 | public long longValue() { 35 | return _underlying.longValue(); 36 | } 37 | 38 | @Override 39 | public float floatValue() { 40 | return _underlying.floatValue(); 41 | } 42 | 43 | @Override 44 | public double doubleValue() { 45 | return _underlying.doubleValue(); 46 | } 47 | 48 | public int getBits() { 49 | return _bits; 50 | } 51 | 52 | @Override 53 | public boolean equals(final Object o) { 54 | if (this == o) { 55 | return true; 56 | } 57 | if (o == null || getClass() != o.getClass()) { 58 | return false; 59 | } 60 | 61 | final Decimal32 decimal32 = (Decimal32) o; 62 | 63 | return _bits == decimal32._bits; 64 | } 65 | 66 | @Override 67 | public int hashCode() { 68 | return _bits; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/adhara/interop-service/corda-decoder/src/main/java/io/adhara/poc/ledger/SignedData.java: -------------------------------------------------------------------------------- 1 | package io.adhara.poc.ledger; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | 9 | import java.util.Collections; 10 | import java.util.List; 11 | 12 | @Data 13 | @AllArgsConstructor 14 | @NoArgsConstructor 15 | public class SignedData { 16 | private static final Logger logger = LoggerFactory.getLogger(SignedData.class); 17 | 18 | private String by; 19 | private String bytes; 20 | private String partialTree; 21 | private Integer platformVersion; 22 | private Integer schemaNumber; 23 | 24 | public boolean hasPlatformVersion() { return platformVersion != null; } 25 | 26 | public boolean hasPartialTree() { return partialTree != null && !partialTree.isEmpty(); } 27 | 28 | public PartialTree getPartialTreeRoot(SecureHash root) { 29 | if (hasPartialTree()) { 30 | List txLeaves = Collections.singletonList(root.rehash()); 31 | MerkleTree txTree = MerkleTree.getMerkleTree(txLeaves); 32 | PartialTree pTree = null; 33 | try { 34 | PartialMerkleTree parTree = PartialMerkleTree.build(txTree, txLeaves); 35 | pTree = parTree.getRoot(); 36 | if (!getPartialTree().equals(pTree.getHash().toString())) { 37 | logger.error("The given hash is not an included leaf in the partial tree"); 38 | } 39 | } catch (Exception e) { 40 | logger.error("Failed to build partial tree from given hash: " + e.getMessage()); 41 | } 42 | return pTree; 43 | } 44 | return null; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/r3/atomic-swap/corda/evm-interop-workflows/src/main/kotlin/com/r3/corda/evminterop/workflows/UnsecureRemoteEvmIdentityFlow.kt: -------------------------------------------------------------------------------- 1 | package com.r3.corda.evminterop.workflows 2 | 3 | import co.paralleluniverse.fibers.Suspendable 4 | import com.r3.corda.evminterop.services.BridgeIdentity 5 | import net.corda.core.flows.FlowLogic 6 | import net.corda.core.flows.InitiatingFlow 7 | import net.corda.core.flows.StartableByRPC 8 | import java.net.URI 9 | 10 | /** 11 | * UnsecureRemoteEvmIdentityFlow associate an EVM identity to a Corda Identity and EVM RPC Endpoint 12 | * Flows using the EVM service run by this Corda Identity will sign with the specified private key 13 | * NOTE: This is a simplistic implementation where the private key is passed in plain text as a 14 | * parameter. A safer implementation is recommended using HSM devices or protocols for offline 15 | * signing. 16 | */ 17 | @InitiatingFlow 18 | @StartableByRPC 19 | class UnsecureRemoteEvmIdentityFlow( 20 | private val ethereumPrivateKey: String, 21 | private val jsonRpcEndpoint: String, 22 | private val chainId: Long = -1, 23 | private val protocolAddress: String, 24 | private val deployerAddress: String 25 | ) : FlowLogic() { 26 | @Suspendable 27 | override fun call() { 28 | 29 | val identity = BridgeIdentity( 30 | privateKey = ethereumPrivateKey, 31 | rpcEndpoint = URI(jsonRpcEndpoint), 32 | chainId = chainId, 33 | protocolAddress = protocolAddress, 34 | deployerAddress = deployerAddress 35 | ) 36 | 37 | identity.authorize(this, ourIdentity.owningKey) 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/adhara/interop-service/corda-decoder/src/main/java/io/adhara/poc/amqp/types/Decimal64.java: -------------------------------------------------------------------------------- 1 | package io.adhara.poc.amqp.types; 2 | 3 | import java.math.BigDecimal; 4 | 5 | public final class Decimal64 extends Number { 6 | private final BigDecimal _underlying; 7 | private final long _bits; 8 | 9 | public Decimal64(BigDecimal underlying) { 10 | _underlying = underlying; 11 | _bits = calculateBits(underlying); 12 | 13 | } 14 | 15 | 16 | public Decimal64(final long bits) { 17 | _bits = bits; 18 | _underlying = calculateBigDecimal(bits); 19 | } 20 | 21 | static BigDecimal calculateBigDecimal(final long bits) { 22 | return BigDecimal.ZERO; 23 | } 24 | 25 | static long calculateBits(final BigDecimal underlying) { 26 | return 0l; // TODO 27 | } 28 | 29 | 30 | @Override 31 | public int intValue() { 32 | return _underlying.intValue(); 33 | } 34 | 35 | @Override 36 | public long longValue() { 37 | return _underlying.longValue(); 38 | } 39 | 40 | @Override 41 | public float floatValue() { 42 | return _underlying.floatValue(); 43 | } 44 | 45 | @Override 46 | public double doubleValue() { 47 | return _underlying.doubleValue(); 48 | } 49 | 50 | public long getBits() { 51 | return _bits; 52 | } 53 | 54 | @Override 55 | public boolean equals(final Object o) { 56 | if (this == o) { 57 | return true; 58 | } 59 | if (o == null || getClass() != o.getClass()) { 60 | return false; 61 | } 62 | 63 | final Decimal64 decimal64 = (Decimal64) o; 64 | 65 | return _bits == decimal64._bits; 66 | } 67 | 68 | @Override 69 | public int hashCode() { 70 | return (int) (_bits ^ (_bits >>> 32)); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/adhara/interop-service/crosschainInterop/api/README.md: -------------------------------------------------------------------------------- 1 | IT IS UNDERSTOOD THAT THE PROOF OF CONCEPT SOFTWARE, DOCUMENTATION, AND ANY UPDATES MAY CONTAIN ERRORS AND ARE PROVIDED 2 | FOR LIMITED EVALUATION ONLY. THE PROOF OF CONCEPT SOFTWARE, THE DOCUMENTATION, AND ANY UPDATES ARE PROVIDED "AS IS" 3 | WITHOUT WARRANTY OF ANY KIND, WHETHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE. 4 | 5 | # Crosschain interop service 6 | 7 | ## Introduction 8 | 9 | The crosschain interop service provides API endpoints to interact with the crosschain interop application SDK. 10 | 11 | ## Problem Description 12 | 13 | The crosschain interop SDKs are decentralised and trustless for the most part, however certain onboarding and setup steps need to be performed. 14 | 15 | Some of these steps are, but not limited to, onboarding proving schemes, onboarding event decoding schemes and adding remote to local account identity mappings. 16 | 17 | In addition to the functioning of the crosschain interop SDK, there is also a need for parties to be able to submit settlement instructions, which is not trustless or decentralised. 18 | 19 | ## Methodology 20 | 21 | ### Setup 22 | 23 | Refer to either [Payment versus Payment (PvP)](pvp/README.md) or [Delivery versus Payment (DvP)](dvp/README.md) for 24 | specific instructions. 25 | 26 | ### Start the API 27 | 28 | 1. The API needs contract build artifacts from the `crosschainInterop` folder: 29 | 30 | ```bash 31 | make setup && make compile 32 | ``` 33 | 34 | 2. The application API can be started with: 35 | 36 | ```bash 37 | npm run start-app 38 | ``` 39 | 40 | 3. The admin API can be started with: 41 | 42 | ```bash 43 | npm run start-admin 44 | ``` 45 | -------------------------------------------------------------------------------- /src/r3/atomic-swap/evm/src/TestToken.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | 3 | /****************************************************************************** 4 | * Copyright 2023 R3 LLC * 5 | * * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); * 7 | * you may not use this file except in compliance with the License. * 8 | * You may obtain a copy of the License at * 9 | * * 10 | * http://www.apache.org/licenses/LICENSE-2.0 * 11 | * * 12 | * Unless required by applicable law or agreed to in writing, software * 13 | * distributed under the License is distributed on an "AS IS" BASIS, * 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 15 | * See the License for the specific language governing permissions and * 16 | * limitations under the License. * 17 | ******************************************************************************/ 18 | 19 | pragma solidity ^0.8.28; 20 | 21 | import "openzeppelin/token/ERC20/ERC20.sol"; 22 | 23 | contract TestToken is ERC20 { 24 | uint256 constant _initial_supply = 1000000; 25 | 26 | constructor(string memory name, string memory symbol) ERC20(name, symbol) { 27 | _mint(msg.sender, _initial_supply * (10 ** decimals())); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/adhara/interop-service/crosschainInterop/contracts/AuthParams.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.8.13; 2 | 3 | abstract contract AuthParams { 4 | 5 | /* 6 | * Encode authentication parameters according to EEA guidelines. 7 | * @param {uint256} networkId The source network identifier to encode for use in authentication. 8 | * @param {address} contractAddress The contract address to encode for use in authentication. 9 | * @param {bytes} functionCallData The function call parameters to append the authentication parameters to. 10 | * @return {bytes} The encoded function call parameters after including the given authentication parameters. 11 | */ 12 | function encodeAuthParams( 13 | uint256 networkId, 14 | address contractAddress, 15 | bytes memory functionCallData 16 | ) internal pure returns (bytes memory) { 17 | return bytes.concat(functionCallData, abi.encodePacked(networkId, contractAddress)); 18 | } 19 | 20 | /* 21 | * Decode authentication parameters according to EEA guidelines. 22 | * @return {uint256} networkId The extracted source network identifier to be used in authentication. 23 | * @return {address} contractAddress The extracted contract address to the authenticated. 24 | */ 25 | function decodeAuthParams() internal pure returns ( 26 | uint256 networkId, 27 | address contractAddress 28 | ) { 29 | bytes calldata allParams = msg.data; 30 | uint256 len = allParams.length; 31 | assembly ("memory-safe") { 32 | calldatacopy(0x0, sub(len, add(52, 8)), 32) 33 | networkId := mload(0) 34 | calldatacopy(12, sub(len, add(20, 8)), 20) 35 | contractAddress := mload(0) 36 | } 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/r3/atomic-swap/corda/evm-interop-workflows/src/main/kotlin/com/r3/corda/evminterop/services/RemoteEVMIdentity.kt: -------------------------------------------------------------------------------- 1 | package com.r3.corda.evminterop.services 2 | 3 | import co.paralleluniverse.fibers.Suspendable 4 | import net.corda.core.flows.FlowLogic 5 | import org.web3j.crypto.RawTransaction 6 | import java.net.URI 7 | import java.security.PublicKey 8 | 9 | interface RemoteEVMIdentity { 10 | 11 | /** 12 | * [rpcEndpoint] defines the EVM node endpoint to connect to 13 | */ 14 | val rpcEndpoint: URI 15 | 16 | /** 17 | * [chainId] defines the blockchain id 18 | */ 19 | val chainId: Long 20 | 21 | /** 22 | * [protocolAddress] defines the protocol contract deployment address on the given network 23 | */ 24 | val protocolAddress: String 25 | 26 | /** 27 | * [deployerAddress] defines the protocol contract deployment address on the given network 28 | */ 29 | val deployerAddress: String 30 | 31 | /** 32 | * Initializes a RemoteEVMIdentity instance 33 | */ 34 | @Suspendable 35 | fun authorize(flowLogic: FlowLogic<*>, authorizedId: PublicKey) 36 | 37 | /** 38 | * Signs a raw transaction before sending it 39 | */ 40 | @Suspendable 41 | fun signMessage(rawTransaction: RawTransaction, chainId: Long) : ByteArray 42 | 43 | /** 44 | * Get currently configured identity's address 45 | */ 46 | fun getAddress() : String 47 | 48 | /** 49 | * Signs some data using the current EVM identity 50 | */ 51 | @Suspendable 52 | fun signData(data: ByteArray) : ByteArray 53 | 54 | /** 55 | * Dispose the current instance of RemoteEVMIdentity 56 | */ 57 | fun dispose() 58 | } 59 | -------------------------------------------------------------------------------- /src/r3/atomic-swap/corda/evm-interop-contracts/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'net.corda.plugins.cordapp' 2 | apply plugin: 'org.jetbrains.kotlin.jvm' 3 | apply plugin: 'kotlin' 4 | apply plugin: 'java' 5 | 6 | repositories { 7 | mavenCentral() 8 | maven { url 'https://download.corda.net/maven/corda-releases' } 9 | maven { url 'https://download.corda.net/maven/corda-dependencies' } 10 | } 11 | 12 | // The module is shipped to Corda Node as Cordapp, although it doesn't have any flows. 13 | cordapp { 14 | targetPlatformVersion corda_platform_version 15 | minimumPlatformVersion corda_platform_version 16 | workflow { 17 | name "EVM Interop Contracts Library" 18 | vendor "Corda Open Source" 19 | licence "Apache License, Version 2.0" 20 | versionId 1 21 | } 22 | sealing.enabled false 23 | signing.enabled false 24 | } 25 | 26 | dependencies { 27 | // Kotlin standard library 28 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" 29 | 30 | // Corda dependencies 31 | cordaProvided("$corda_core_release_group:corda-core:$corda_core_release_version") 32 | 33 | // Web3j dependencies 34 | api ("org.web3j:core:$web3jVersion") { transitive = true } 35 | 36 | // Project dependencies 37 | api project(':evm-interop-common') 38 | 39 | // test dependencies 40 | testImplementation "org.jetbrains.kotlin:kotlin-test:$kotlin_version" 41 | testImplementation "org.junit.jupiter:junit-jupiter-api:$junit_version" 42 | testImplementation "org.junit.jupiter:junit-jupiter-engine:$junit_version" 43 | testImplementation "org.mockito:mockito-core:$mockitoVersion" 44 | testImplementation "org.mockito:mockito-inline:$mockitoVersion" 45 | } 46 | -------------------------------------------------------------------------------- /src/adhara/interop-service/cordapp/contracts/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'net.corda.plugins.cordapp' 2 | apply plugin: 'net.corda.plugins.cordformation' 3 | 4 | cordapp { 5 | targetPlatformVersion corda_platform_version 6 | minimumPlatformVersion corda_platform_version 7 | contract { 8 | name "Cordapp-example Contracts" 9 | vendor "Corda Open Source" 10 | licence "Apache License, Version 2.0" 11 | versionId 1 12 | } 13 | } 14 | 15 | sourceSets { 16 | main{ 17 | java { 18 | srcDir 'src/main/java' 19 | java.outputDir = file('bin/main') 20 | } 21 | } 22 | test{ 23 | java{ 24 | srcDir 'src/test/java' 25 | java.outputDir = file('bin/test') 26 | } 27 | } 28 | } 29 | 30 | dependencies { 31 | // Corda dependencies. 32 | cordaProvided "$corda_core_release_group:corda-core:$corda_core_release_version" 33 | cordaProvided "$corda_release_group:corda:$corda_release_version" 34 | testImplementation "$corda_release_group:corda-node-driver:$corda_release_version" 35 | 36 | implementation "javax.persistence:javax.persistence-api:$persistence_version" 37 | implementation "jakarta.annotation:jakarta.annotation-api:$annotation_version" 38 | implementation 'org.hibernate:hibernate-core:5.6.0.Final' // Use the appropriate version for your project 39 | 40 | testImplementation "$corda_core_release_group:corda-core-test-utils:$corda_core_release_version" 41 | testImplementation "$corda_core_release_group:corda-test-utils:$corda_core_release_version" 42 | 43 | testImplementation group: 'com.google.guava', name: 'guava', version: '23.5-jre' 44 | testImplementation "junit:junit:$junit_version" 45 | } -------------------------------------------------------------------------------- /src/adhara/interop-service/corda-decoder/src/main/java/io/adhara/poc/rest/controller/DecodeAndVerifyTransactionController.java: -------------------------------------------------------------------------------- 1 | package io.adhara.poc.rest.controller; 2 | 3 | import io.adhara.poc.ledger.*; 4 | import io.adhara.poc.rest.model.LedgerTransaction; 5 | 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | import org.springframework.http.MediaType; 9 | import org.springframework.http.ResponseEntity; 10 | import org.springframework.web.bind.annotation.*; 11 | 12 | import java.net.URI; 13 | import java.util.*; 14 | 15 | import org.springframework.web.servlet.support.ServletUriComponentsBuilder; 16 | 17 | @RestController 18 | @RequestMapping(path = "/decodeAndVerifyTransaction") 19 | public class DecodeAndVerifyTransactionController { 20 | private static final Logger logger = LoggerFactory.getLogger(DecodeAndVerifyTransactionController.class); 21 | 22 | @PostMapping(path = "/", consumes = "application/json", produces = "application/json") 23 | public ResponseEntity decodeAndVerifyEvent( 24 | @RequestBody LedgerTransaction ledgerTransaction) 25 | throws Exception { 26 | 27 | HashMap result = new HashMap<>(); 28 | try { 29 | List> components = new ArrayList<>(); 30 | Decoder.parseCordaSerialization(ledgerTransaction.getEncodedInfo(), 0, "", components); 31 | SignatureProof proof = new SignatureProof(ledgerTransaction.getEncodedInfo(), components); 32 | result.put("result", proof.verify()); 33 | } catch (Exception e) { 34 | logger.error(e.getMessage()); 35 | } 36 | 37 | URI location = ServletUriComponentsBuilder.fromCurrentRequest().build().toUri(); 38 | return ResponseEntity.created(location).contentType(MediaType.APPLICATION_JSON).body(result); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/adhara/interop-service/cordapp/clients/src/main/java/net/corda/samples/example/webserver/NodeRPCConnection.java: -------------------------------------------------------------------------------- 1 | package net.corda.samples.example.webserver; 2 | 3 | import net.corda.client.rpc.CordaRPCClient; 4 | import net.corda.client.rpc.CordaRPCConnection; 5 | import net.corda.core.messaging.CordaRPCOps; 6 | import net.corda.core.utilities.NetworkHostAndPort; 7 | import org.springframework.beans.factory.annotation.Value; 8 | import org.springframework.stereotype.Component; 9 | 10 | import javax.annotation.PostConstruct; 11 | import javax.annotation.PreDestroy; 12 | 13 | // Wraps an RPC connection to a Corda node. 14 | @Component 15 | public class NodeRPCConnection implements AutoCloseable { 16 | // The host of the node we are connecting to. 17 | @Value("${config.rpc.host}") 18 | private String host; 19 | // The RPC port of the node we are connecting to. 20 | @Value("${config.rpc.username}") 21 | private String username; 22 | // The username for logging into the RPC client. 23 | @Value("${config.rpc.password}") 24 | private String password; 25 | // The password for logging into the RPC client. 26 | @Value("${config.rpc.port}") 27 | private int rpcPort; 28 | 29 | private CordaRPCConnection rpcConnection; 30 | CordaRPCOps proxy; 31 | 32 | @PostConstruct 33 | public void initialiseNodeRPCConnection() { 34 | NetworkHostAndPort rpcAddress = new NetworkHostAndPort(host, rpcPort); 35 | CordaRPCClient rpcClient = new CordaRPCClient(rpcAddress); 36 | rpcConnection = rpcClient.start(username, password); 37 | proxy = rpcConnection.getProxy(); 38 | } 39 | 40 | @PreDestroy 41 | public void close() { 42 | rpcConnection.notifyServerAndClose(); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/r3/atomic-swap/corda/evm-interop-workflows/src/main/kotlin/com/r3/corda/evminterop/services/AuthorizedSigner.kt: -------------------------------------------------------------------------------- 1 | package com.r3.corda.evminterop.services 2 | 3 | import net.corda.core.contracts.TimeWindow 4 | import java.security.PublicKey 5 | import java.time.Instant 6 | import java.util.* 7 | 8 | /** 9 | * Helper class to implement a remote signing feature probably using WalletConnect protocol 10 | */ 11 | class AuthorizedSigner private constructor( 12 | 13 | /** 14 | * [owningKey] of the authorized Corda Party or Account 15 | */ 16 | val owningKey: PublicKey, 17 | 18 | /** 19 | * [account] of the authorized signer on the authorizing platform 20 | */ 21 | val account: String, 22 | 23 | /** 24 | * [timeout] of the validity of this authorization 25 | */ 26 | val timeout: TimeWindow = TimeWindow.between(Instant.MIN, Instant.MAX) 27 | 28 | ) { 29 | 30 | companion object { 31 | /** 32 | * Connects and request authorization according to the parameters 33 | * @param [owningKey] of the authorized Party 34 | * @param [account] of the authorized signer 35 | * @param [timeout] of the validity of this authorization 36 | * @param [flowId] of the authorized flow 37 | */ 38 | fun requestAuthorization( 39 | owningKey: PublicKey, 40 | account: String, 41 | timeout: TimeWindow = TimeWindow.between(Instant.MIN, Instant.MAX) 42 | ) : AuthorizedSigner { 43 | return AuthorizedSigner(owningKey, account, timeout) 44 | } 45 | } 46 | 47 | /** 48 | * Invalidates the current signing authorization, so that no other flow can use it 49 | */ 50 | fun dispose() { 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/r3/atomic-swap/corda/evm-interop-workflows/src/main/kotlin/com/r3/corda/evminterop/workflows/eth2eth/GetTransactionFlow.kt: -------------------------------------------------------------------------------- 1 | package com.r3.corda.evminterop.workflows.eth2eth 2 | 3 | import co.paralleluniverse.fibers.Suspendable 4 | import com.r3.corda.evminterop.services.evmInterop 5 | import net.corda.core.flows.FlowLogic 6 | import net.corda.core.flows.InitiatingFlow 7 | import net.corda.core.flows.StartableByRPC 8 | import net.corda.core.utilities.ProgressTracker 9 | import net.corda.core.utilities.loggerFor 10 | 11 | /** 12 | * Get a transaction by its hash 13 | * 14 | * @property hash the hash of the transaction 15 | * @return the ethereum transaction receipt of the transfer. 16 | */ 17 | @StartableByRPC 18 | @InitiatingFlow 19 | class GetTransactionFlow( 20 | private val hash: String 21 | ) : FlowLogic() { 22 | 23 | @Suppress("ClassName") 24 | companion object { 25 | object CONNECT_WEB3 : ProgressTracker.Step("Connecting WEB3 API provider.") 26 | object QUERY_TRANSACTION : ProgressTracker.Step("Querying transaction data.") 27 | 28 | fun tracker() = ProgressTracker( 29 | CONNECT_WEB3, 30 | QUERY_TRANSACTION 31 | ) 32 | 33 | val log = loggerFor() 34 | } 35 | 36 | override val progressTracker: ProgressTracker = tracker() 37 | 38 | @Suspendable 39 | override fun call(): com.r3.corda.evminterop.dto.Transaction { 40 | progressTracker.currentStep = CONNECT_WEB3 41 | val web3 = evmInterop().web3Provider() 42 | 43 | progressTracker.currentStep = QUERY_TRANSACTION 44 | val transaction = await(web3.getTransactionByHash(hash)) 45 | 46 | return transaction 47 | } 48 | } 49 | 50 | -------------------------------------------------------------------------------- /docs/adhara/bank_side_patterns.md: -------------------------------------------------------------------------------- 1 | # Bank Side patterns 2 | 3 | ## Introduction 4 | 5 | Banks are looking for consistency and standardisation when it comes to connecting to different digital platforms and managing interoperability between different settlement legs. 6 | 7 | At a simplistic level, banks will be running gateways to different platforms. These gateways could be using different technologies. Below is an image showing the generic components that banks will need to manage. The image is showing a corda gateway and an enterprise ethereum gateway, but this pattern can be extended to other technology stacks. 8 | 9 | ![Bank side generic pattern](./img/bank_side_generic_pattern.png) 10 | 11 | ## Risk as platforms scale 12 | 13 | As the platforms scale, banks will need to manage multiple gateways, interfaces, data formats and interop mechanisms. By establishing some standard patterns, we can provide guardrails to platform providers to ensure that the connections to their platforms, and the interop mechanisms involved, are well understood by the banks and easy to deploy. 14 | 15 | ![Risks as platforms scale](./img/risks_as_platforms_scale.png) 16 | 17 | ## Aspiration 18 | 19 | Harmonia aspires to provide those guardrails in order to be able to generate common/open source interfaces and protocols across apps and DLT protocols. 20 | 21 | ![Aspiration](./img/aspiration.png) 22 | 23 | ## Interfaces 24 | 25 | The interfaces to consider depends on the ecosystem of banks, but consists mainly of the following 4: 26 | 27 | - The HSM interface (already largely standardised to use PKCS#11) 28 | - The Bank Side API 29 | - The Interop interface 30 | - The Network interface (well documented across the major DLT protocols) 31 | 32 | ![Interfaces](./img/interfaces.png) 33 | 34 | -------------------------------------------------------------------------------- /src/r3/atomic-swap/corda/evm-interop-workflows/src/main/kotlin/com/r3/corda/evminterop/workflows/internal/Utils.kt: -------------------------------------------------------------------------------- 1 | package com.r3.corda.evminterop.workflows.internal 2 | 3 | class AggregateResult(val sequence: Collection, val accumulator: TAccumulate) { 4 | operator fun component1(): Collection = sequence 5 | operator fun component2(): TAccumulate = accumulator 6 | } 7 | 8 | /** 9 | * Conditional take-while aggregated sum of a sequence 10 | */ 11 | fun Sequence.takeWhileAggregate( 12 | seed: TAccumulate, 13 | func: (TAccumulate, TSource) -> TAccumulate, 14 | predicate: (TAccumulate) -> Boolean 15 | ): AggregateResult { 16 | var accumulator = seed 17 | val result = mutableListOf() 18 | for(it in this) { 19 | val tempAccumulator = func(accumulator, it) 20 | if (predicate(tempAccumulator)) { 21 | accumulator = tempAccumulator 22 | result.add(it) 23 | } else { 24 | break 25 | } 26 | } 27 | return AggregateResult(result, accumulator) 28 | } 29 | 30 | /** 31 | * Conditional take-until aggregated sum of a sequence 32 | */ 33 | fun Sequence.takeUntilAggregate( 34 | seed: TAccumulate, 35 | func: (TAccumulate, TSource) -> TAccumulate, 36 | predicate: (TAccumulate) -> Boolean 37 | ): AggregateResult { 38 | var accumulator = seed 39 | val result = mutableListOf() 40 | for(it in this) { 41 | result.add(it) 42 | accumulator = func(accumulator, it) 43 | if (predicate(accumulator)) { 44 | break 45 | } 46 | } 47 | return AggregateResult(result, accumulator) 48 | } -------------------------------------------------------------------------------- /src/adhara/interop-service/corda-decoder/src/main/java/io/adhara/poc/amqp/codec/DroppingWritableBuffer.java: -------------------------------------------------------------------------------- 1 | package io.adhara.poc.amqp.codec; 2 | 3 | import java.nio.ByteBuffer; 4 | import java.nio.charset.StandardCharsets; 5 | 6 | public class DroppingWritableBuffer implements WritableBuffer { 7 | private int _pos = 0; 8 | 9 | @Override 10 | public boolean hasRemaining() { 11 | return true; 12 | } 13 | 14 | @Override 15 | public void put(byte b) { 16 | _pos += 1; 17 | } 18 | 19 | @Override 20 | public void putFloat(float f) { 21 | _pos += 4; 22 | } 23 | 24 | @Override 25 | public void putDouble(double d) { 26 | _pos += 8; 27 | } 28 | 29 | @Override 30 | public void put(byte[] src, int offset, int length) { 31 | _pos += length; 32 | } 33 | 34 | @Override 35 | public void putShort(short s) { 36 | _pos += 2; 37 | } 38 | 39 | @Override 40 | public void putInt(int i) { 41 | _pos += 4; 42 | } 43 | 44 | @Override 45 | public void putLong(long l) { 46 | _pos += 8; 47 | } 48 | 49 | @Override 50 | public int remaining() { 51 | return Integer.MAX_VALUE - _pos; 52 | } 53 | 54 | @Override 55 | public int position() { 56 | return _pos; 57 | } 58 | 59 | @Override 60 | public void position(int position) { 61 | _pos = position; 62 | } 63 | 64 | @Override 65 | public void put(ByteBuffer payload) { 66 | _pos += payload.remaining(); 67 | payload.position(payload.limit()); 68 | } 69 | 70 | @Override 71 | public int limit() { 72 | return Integer.MAX_VALUE; 73 | } 74 | 75 | @Override 76 | public void put(ReadableBuffer payload) { 77 | _pos += payload.remaining(); 78 | payload.position(payload.limit()); 79 | } 80 | 81 | @Override 82 | public void put(String value) { 83 | _pos += value.getBytes(StandardCharsets.UTF_8).length; 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /docs/r3/bounded_visibility.md: -------------------------------------------------------------------------------- 1 | # Bounded Visibility 2 | 3 | A private, permissioned distributed ledger such as Corda’s does not expose the entire history of all ledger transactions to all nodes in the network. The ability to view a transaction is typically limited to network peers who are parties either to that transaction or to subsequent transactions which include that transaction in their backchain. 4 | 5 | This means that we have to be precise about who, on a Corda network, is being asked to provide evidence that a transaction has taken place, which in turn means that we may have to consider whether they are a trustworthy informant. 6 | 7 | Suppose that the USD network in our cross-chain swap example is a Corda network. Having prepared the transfer of the asset from Bob@GBP to Alice@GBP, we want to know that the transfer of the asset from Alice@USD to Bob@USD has also been prepared, completing the first phase of a two-phase commit, before proceeding to commit the transfer of the asset from Bob@GBP to Alice@GBP. 8 | 9 | Because the interests of Alice@USD are aligned with those of Alice@GBP, there is an incentive for Alice@USD to give a false positive report so that Alice@GBP will unfairly receive the benefit of the swap, without Bob@USD receiving their side of the exchange. 10 | 11 | If we instead rely on Bob@USD, who will also see the transaction which prepares the asset transfer from Alice@USD to Bob@USD, then we know that Bob@USD has no incentive to give a false negative report, since Bob@USD cannot receive the asset unless the transfer has genuinely been prepared. 12 | 13 | Visibility may also be curtailed by events such as a node leaving a network, so that it is no longer available to consult, or ledger transactions moving out of a time-limited observation window and needing to be recalled from long-term storage. 14 | -------------------------------------------------------------------------------- /src/r3/atomic-swap/corda/evm-interop-workflows/src/main/kotlin/com/r3/corda/evminterop/workflows/eth2eth/Erc20TokensTotalSupplyFlow.kt: -------------------------------------------------------------------------------- 1 | package com.r3.corda.evminterop.workflows.eth2eth 2 | 3 | import co.paralleluniverse.fibers.Suspendable 4 | import com.r3.corda.evminterop.services.evmInterop 5 | import net.corda.core.flows.FlowLogic 6 | import net.corda.core.flows.InitiatingFlow 7 | import net.corda.core.flows.StartableByRPC 8 | import net.corda.core.utilities.ProgressTracker 9 | import net.corda.core.utilities.loggerFor 10 | import java.math.BigInteger 11 | 12 | /** 13 | * Query ERC20 tokens for total supply. 14 | * 15 | * @property tokenAddress the address of the ERC20 contract representing the token being queried. 16 | * @return the ERC20's total supply. 17 | */ 18 | @StartableByRPC 19 | @InitiatingFlow 20 | class Erc20TokensTotalSupplyFlow( 21 | private val tokenAddress: String 22 | ) : FlowLogic() { 23 | 24 | @Suppress("ClassName") 25 | companion object { 26 | object CONNECT_ERC20 : ProgressTracker.Step("Connecting ERC20 contract provider.") 27 | object QUERYING_ERC20_SUPPLY : ProgressTracker.Step("Querying ERC20 total supply.") 28 | 29 | fun tracker() = ProgressTracker( 30 | CONNECT_ERC20, 31 | QUERYING_ERC20_SUPPLY 32 | ) 33 | 34 | val log = loggerFor() 35 | } 36 | 37 | override val progressTracker: ProgressTracker = tracker() 38 | 39 | @Suspendable 40 | override fun call(): BigInteger { 41 | progressTracker.currentStep = CONNECT_ERC20 42 | val erc20 = evmInterop().erc20Provider(tokenAddress) 43 | 44 | progressTracker.currentStep = QUERYING_ERC20_SUPPLY 45 | val totalSupply = await(erc20.totalSupply()) 46 | 47 | return totalSupply 48 | } 49 | } -------------------------------------------------------------------------------- /src/r3/atomic-swap/corda/.gitignore: -------------------------------------------------------------------------------- 1 | # Eclipse, ctags, Mac metadata, log files 2 | .classpath 3 | .project 4 | tags 5 | .DS_Store 6 | *.log 7 | *.log.gz 8 | *.orig 9 | 10 | .gradle 11 | 12 | # General build files 13 | **/build/* 14 | !docs/build/* 15 | 16 | lib/dokka.jar 17 | 18 | ### JetBrains template 19 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio 20 | 21 | *.iml 22 | 23 | ## Directory-based project format: 24 | #.idea 25 | 26 | # if you remove the above rule, at least ignore the following: 27 | 28 | # Specific files to avoid churn 29 | .idea/*.xml 30 | .idea/copyright 31 | .idea/jsLibraryMappings.xml 32 | .idea/runConfigurations/*.xml 33 | .idea/codeStyles/*.xml 34 | 35 | # User-specific stuff: 36 | .idea/tasks.xml 37 | .idea/dictionaries 38 | 39 | # Sensitive or high-churn files: 40 | .idea/dataSources.ids 41 | .idea/dataSources.xml 42 | .idea/sqlDataSources.xml 43 | .idea/dynamic.xml 44 | .idea/uiDesigner.xml 45 | 46 | # Gradle: 47 | .idea/libraries 48 | 49 | # Mongo Explorer plugin: 50 | .idea/mongoSettings.xml 51 | 52 | ## File-based project format: 53 | *.ipr 54 | *.iws 55 | 56 | ## Plugin-specific files: 57 | 58 | # IntelliJ 59 | /out/ 60 | workflows/out/ 61 | contracts/out/ 62 | clients/out/ 63 | 64 | # mpeltonen/sbt-idea plugin 65 | .idea_modules/ 66 | 67 | # JIRA plugin 68 | atlassian-ide-plugin.xml 69 | 70 | # Crashlytics plugin (for Android Studio and IntelliJ) 71 | com_crashlytics_export_strings.xml 72 | crashlytics.properties 73 | crashlytics-build.properties 74 | 75 | # docs related 76 | docs/virtualenv/ 77 | 78 | # if you use the installQuasar task 79 | #lib 80 | **/bin 81 | 82 | # Mac users can use Jenv to set upJava version by producing this fiel, should be ignored: 83 | .java-version 84 | 85 | # github.properties containing user's github token 86 | github.properties -------------------------------------------------------------------------------- /src/r3/atomic-swap/corda/evm-interop-workflows/src/main/kotlin/com/r3/corda/evminterop/workflows/eth2eth/GetTransactionReceiptFlow.kt: -------------------------------------------------------------------------------- 1 | package com.r3.corda.evminterop.workflows.eth2eth 2 | 3 | import co.paralleluniverse.fibers.Suspendable 4 | import com.r3.corda.evminterop.services.evmInterop 5 | import net.corda.core.flows.FlowLogic 6 | import net.corda.core.flows.InitiatingFlow 7 | import net.corda.core.flows.StartableByRPC 8 | import net.corda.core.utilities.ProgressTracker 9 | import net.corda.core.utilities.loggerFor 10 | 11 | /** 12 | * Get a transaction receipt by its transaction hash 13 | * 14 | * @property hash the hash of the transaction 15 | * @return the ethereum transaction receipt of the transfer. 16 | */ 17 | @StartableByRPC 18 | @InitiatingFlow 19 | class GetTransactionReceiptFlow( 20 | private val hash: String 21 | ) : FlowLogic() { 22 | 23 | @Suppress("ClassName") 24 | companion object { 25 | object CONNECT_WEB3 : ProgressTracker.Step("Connecting WEB3 API provider.") 26 | object QUERY_TRANSACTION_RECEIPT : ProgressTracker.Step("Querying transaction receipt.") 27 | 28 | fun tracker() = ProgressTracker( 29 | CONNECT_WEB3, 30 | QUERY_TRANSACTION_RECEIPT 31 | ) 32 | 33 | val log = loggerFor() 34 | } 35 | 36 | override val progressTracker: ProgressTracker = tracker() 37 | 38 | @Suspendable 39 | override fun call(): com.r3.corda.evminterop.dto.TransactionReceipt { 40 | progressTracker.currentStep = CONNECT_WEB3 41 | val web3 = evmInterop().web3Provider() 42 | 43 | progressTracker.currentStep = QUERY_TRANSACTION_RECEIPT 44 | val receipt = await(web3.getTransactionReceiptByHash(hash)) 45 | 46 | return receipt 47 | } 48 | } 49 | 50 | -------------------------------------------------------------------------------- /src/adhara/interop-service/corda-decoder/src/main/java/io/adhara/poc/amqp/codec/NullType.java: -------------------------------------------------------------------------------- 1 | package io.adhara.poc.amqp.codec; 2 | 3 | import java.util.Collection; 4 | import java.util.Collections; 5 | 6 | public final class NullType extends AbstractPrimitiveType { 7 | private final NullEncoding _nullEncoding; 8 | 9 | NullType(final EncoderImpl encoder, final DecoderImpl decoder) { 10 | _nullEncoding = new NullEncoding(encoder, decoder); 11 | encoder.register(Void.class, this); 12 | decoder.register(this); 13 | } 14 | 15 | public Class getTypeClass() { 16 | return Void.class; 17 | } 18 | 19 | public NullEncoding getEncoding(final Void val) { 20 | return _nullEncoding; 21 | } 22 | 23 | 24 | public NullEncoding getCanonicalEncoding() { 25 | return _nullEncoding; 26 | } 27 | 28 | public Collection getAllEncodings() { 29 | return Collections.singleton(_nullEncoding); 30 | } 31 | 32 | public void write() { 33 | _nullEncoding.write(); 34 | } 35 | 36 | private class NullEncoding extends FixedSizePrimitiveTypeEncoding { 37 | 38 | public NullEncoding(final EncoderImpl encoder, final DecoderImpl decoder) { 39 | super(encoder, decoder); 40 | } 41 | 42 | @Override 43 | protected int getFixedSize() { 44 | return 0; 45 | } 46 | 47 | @Override 48 | public byte getEncodingCode() { 49 | return EncodingCodes.NULL; 50 | } 51 | 52 | public NullType getType() { 53 | return NullType.this; 54 | } 55 | 56 | public void writeValue(final Void val) { 57 | } 58 | 59 | public void writeValue() { 60 | } 61 | 62 | public boolean encodesSuperset(final TypeEncoding encoding) { 63 | return encoding == this; 64 | } 65 | 66 | public Void readValue() { 67 | return null; 68 | } 69 | 70 | public void write() { 71 | writeConstructor(); 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/adhara/interop-service/corda-decoder/src/main/java/io/adhara/poc/amqp/codec/Decimal32Type.java: -------------------------------------------------------------------------------- 1 | package io.adhara.poc.amqp.codec; 2 | 3 | import io.adhara.poc.amqp.types.Decimal32; 4 | 5 | import java.util.Collection; 6 | import java.util.Collections; 7 | 8 | public class Decimal32Type extends AbstractPrimitiveType { 9 | private final Decimal32Encoding _decimal32Encoder; 10 | 11 | Decimal32Type(final EncoderImpl encoder, final DecoderImpl decoder) { 12 | _decimal32Encoder = new Decimal32Encoding(encoder, decoder); 13 | encoder.register(Decimal32.class, this); 14 | decoder.register(this); 15 | } 16 | 17 | public Class getTypeClass() { 18 | return Decimal32.class; 19 | } 20 | 21 | public Decimal32Encoding getEncoding(final Decimal32 val) { 22 | return _decimal32Encoder; 23 | } 24 | 25 | 26 | public Decimal32Encoding getCanonicalEncoding() { 27 | return _decimal32Encoder; 28 | } 29 | 30 | public Collection getAllEncodings() { 31 | return Collections.singleton(_decimal32Encoder); 32 | } 33 | 34 | private class Decimal32Encoding extends FixedSizePrimitiveTypeEncoding { 35 | 36 | public Decimal32Encoding(final EncoderImpl encoder, final DecoderImpl decoder) { 37 | super(encoder, decoder); 38 | } 39 | 40 | @Override 41 | protected int getFixedSize() { 42 | return 4; 43 | } 44 | 45 | @Override 46 | public byte getEncodingCode() { 47 | return EncodingCodes.DECIMAL32; 48 | } 49 | 50 | public Decimal32Type getType() { 51 | return Decimal32Type.this; 52 | } 53 | 54 | public void writeValue(final Decimal32 val) { 55 | getEncoder().writeRaw(val.getBits()); 56 | } 57 | 58 | public boolean encodesSuperset(final TypeEncoding encoding) { 59 | return (getType() == encoding.getType()); 60 | } 61 | 62 | public Decimal32 readValue() { 63 | return new Decimal32(getDecoder().readRawInt()); 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/adhara/interop-service/corda-decoder/src/main/java/io/adhara/poc/amqp/codec/Decimal64Type.java: -------------------------------------------------------------------------------- 1 | package io.adhara.poc.amqp.codec; 2 | 3 | import io.adhara.poc.amqp.types.Decimal64; 4 | 5 | import java.util.Collection; 6 | import java.util.Collections; 7 | 8 | public class Decimal64Type extends AbstractPrimitiveType { 9 | private final Decimal64Encoding _decimal64Encoder; 10 | 11 | Decimal64Type(final EncoderImpl encoder, final DecoderImpl decoder) { 12 | _decimal64Encoder = new Decimal64Encoding(encoder, decoder); 13 | encoder.register(Decimal64.class, this); 14 | decoder.register(this); 15 | } 16 | 17 | public Class getTypeClass() { 18 | return Decimal64.class; 19 | } 20 | 21 | public Decimal64Encoding getEncoding(final Decimal64 val) { 22 | return _decimal64Encoder; 23 | } 24 | 25 | 26 | public Decimal64Encoding getCanonicalEncoding() { 27 | return _decimal64Encoder; 28 | } 29 | 30 | public Collection getAllEncodings() { 31 | return Collections.singleton(_decimal64Encoder); 32 | } 33 | 34 | private class Decimal64Encoding extends FixedSizePrimitiveTypeEncoding { 35 | 36 | public Decimal64Encoding(final EncoderImpl encoder, final DecoderImpl decoder) { 37 | super(encoder, decoder); 38 | } 39 | 40 | @Override 41 | protected int getFixedSize() { 42 | return 8; 43 | } 44 | 45 | @Override 46 | public byte getEncodingCode() { 47 | return EncodingCodes.DECIMAL64; 48 | } 49 | 50 | public Decimal64Type getType() { 51 | return Decimal64Type.this; 52 | } 53 | 54 | public void writeValue(final Decimal64 val) { 55 | getEncoder().writeRaw(val.getBits()); 56 | } 57 | 58 | public boolean encodesSuperset(final TypeEncoding encoding) { 59 | return (getType() == encoding.getType()); 60 | } 61 | 62 | public Decimal64 readValue() { 63 | return new Decimal64(getDecoder().readRawLong()); 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/adhara/interop-service/crosschainInterop/src/CrosschainSDKUtils/logger.js: -------------------------------------------------------------------------------- 1 | const winston = require('winston'); 2 | 3 | function init(config, dependencies){ 4 | 5 | if(config.logLevel !== 'error' 6 | && config.logLevel !== 'warn' 7 | && config.logLevel !== 'info' 8 | //&& config.logLevel !== 'http' 9 | //&& config.logLevel !== 'verbose' 10 | && config.logLevel !== 'debug' 11 | && config.logLevel !== 'silly' 12 | && config.logLevel !== 'silent' 13 | ){ 14 | console.log('Unsupported logging level set in configuration') 15 | return Error('Unsupported logging level set in configuration') 16 | } 17 | 18 | let format = winston.format.combine( 19 | winston.format.timestamp(), 20 | winston.format.errors({stack: true}), 21 | winston.format.prettyPrint(), 22 | winston.format.align(), 23 | winston.format.printf((info) => `[${info.timestamp}] ${info.level}: ${info.message}`) 24 | ) 25 | if (process.env.NODE_ENV === 'production') { 26 | format = winston.format.combine( 27 | winston.format.timestamp(), 28 | winston.format.errors({stack: true}), 29 | winston.format.json(), 30 | winston.format.prettyPrint(), 31 | winston.format.align(), 32 | winston.format.printf((info) => `[${info.timestamp}] ${info.level}: ${info.message}`) 33 | ) 34 | } 35 | 36 | const logger = winston.createLogger({ 37 | level: config.logLevel === 'silent' ? 'debug' : config.logLevel, 38 | format, 39 | transports: [ 40 | new winston.transports.Console({level: config.logLevel === 'silent' ? 'debug' : config.logLevel, silent: (config.logLevel === 'silent')}) 41 | ] 42 | }) 43 | 44 | function log(level, message, ...meta){ 45 | logger.log(level, message, meta) 46 | } 47 | 48 | return { 49 | log 50 | } 51 | } 52 | 53 | module.exports = init 54 | -------------------------------------------------------------------------------- /src/r3/atomic-swap/corda/evm-interop-workflows/src/main/kotlin/com/r3/corda/evminterop/workflows/eth2eth/Erc20TokensBalanceFlow.kt: -------------------------------------------------------------------------------- 1 | package com.r3.corda.evminterop.workflows.eth2eth 2 | 3 | import co.paralleluniverse.fibers.Suspendable 4 | import com.r3.corda.evminterop.services.evmInterop 5 | import net.corda.core.flows.FlowLogic 6 | import net.corda.core.flows.InitiatingFlow 7 | import net.corda.core.flows.StartableByRPC 8 | import net.corda.core.utilities.ProgressTracker 9 | import net.corda.core.utilities.loggerFor 10 | import java.math.BigInteger 11 | 12 | /** 13 | * Query an address for ERC20 tokens balance. 14 | * 15 | * @property tokenAddress the address of the ERC20 contract representing the token for which the balance is queried. 16 | * @property holderAddress the address of the ERC20 holder whose balance is being queried for. 17 | * @return the ERC20's total supply. 18 | */ 19 | @StartableByRPC 20 | @InitiatingFlow 21 | class Erc20TokensBalanceFlow( 22 | private val tokenAddress: String, 23 | private val holderAddress: String 24 | ) : FlowLogic() { 25 | 26 | @Suppress("ClassName") 27 | companion object { 28 | object CONNECT_ERC20 : ProgressTracker.Step("Connecting ERC20 contract provider.") 29 | object QUERYING_ERC20_BALANCE : ProgressTracker.Step("Querying address for ERC20 balance.") 30 | 31 | fun tracker() = ProgressTracker( 32 | CONNECT_ERC20, 33 | QUERYING_ERC20_BALANCE 34 | ) 35 | 36 | val log = loggerFor() 37 | } 38 | 39 | override val progressTracker: ProgressTracker = tracker() 40 | 41 | @Suspendable 42 | override fun call(): BigInteger { 43 | progressTracker.currentStep = CONNECT_ERC20 44 | val erc20 = evmInterop().erc20Provider(tokenAddress) 45 | 46 | progressTracker.currentStep = QUERYING_ERC20_BALANCE 47 | val balance = await(erc20.balanceOf(holderAddress)) 48 | 49 | return balance 50 | } 51 | } -------------------------------------------------------------------------------- /src/r3/atomic-swap/corda/evm-interop-workflows/src/main/kotlin/com/r3/corda/evminterop/services/IWeb3.kt: -------------------------------------------------------------------------------- 1 | package com.r3.corda.evminterop.services 2 | 3 | import com.r3.corda.evminterop.dto.Block 4 | import com.r3.corda.evminterop.dto.Transaction 5 | import com.r3.corda.evminterop.dto.TransactionReceipt 6 | import com.r3.corda.evminterop.dto.TransactionReceiptLog 7 | import net.corda.core.flows.FlowExternalOperation 8 | import java.math.BigInteger 9 | 10 | interface IWeb3 { 11 | 12 | /** 13 | * Debug API only available on hardhat test networks 14 | */ 15 | fun evmSetNextBlockTimestamp(timestamp: BigInteger) 16 | 17 | fun getEvents(address: String) : FlowExternalOperation 18 | 19 | /** 20 | * Retrieve a block header given its block number 21 | * @param fullTransactionObjects whether or not to retrieve also the transactions included in the block 22 | */ 23 | fun getBlockByNumber(number: BigInteger, fullTransactionObjects: Boolean) : FlowExternalOperation 24 | 25 | /** 26 | * Retrieve a block header given the block hash 27 | * @param fullTransactionObjects whether or not to retrieve also the transactions included in the block 28 | */ 29 | fun getBlockByHash(hash: String, fullTransactionObjects: Boolean) : FlowExternalOperation 30 | 31 | /** 32 | * Retrieve a transaction given its hash 33 | */ 34 | fun getTransactionByHash(hash: String) : FlowExternalOperation 35 | 36 | /** 37 | * Retrieve a transaction receipt given the transaction hash 38 | */ 39 | fun getTransactionReceiptByHash(hash: String) : FlowExternalOperation 40 | 41 | /** 42 | * Retrieve all transaction receipts for a given block 43 | */ 44 | fun getBlockReceipts(blockNumber: BigInteger) : FlowExternalOperation> 45 | 46 | /** 47 | * Signs some data using the current EVM identity 48 | */ 49 | fun signData(data: ByteArray) : ByteArray 50 | } 51 | -------------------------------------------------------------------------------- /src/adhara/interop-service/corda-decoder/src/main/java/io/adhara/poc/amqp/codec/UnsignedLongElement.java: -------------------------------------------------------------------------------- 1 | package io.adhara.poc.amqp.codec; 2 | 3 | import io.adhara.poc.amqp.types.UnsignedLong; 4 | 5 | import java.nio.ByteBuffer; 6 | 7 | class UnsignedLongElement extends AtomicElement { 8 | 9 | private final UnsignedLong _value; 10 | 11 | UnsignedLongElement(Element parent, Element prev, UnsignedLong ul) { 12 | super(parent, prev); 13 | _value = ul; 14 | } 15 | 16 | @Override 17 | public int size() { 18 | if (isElementOfArray()) { 19 | final ArrayElement parent = (ArrayElement) parent(); 20 | if (parent.constructorType() == ArrayElement.TINY) { 21 | if (_value.longValue() == 0l) { 22 | return 0; 23 | } else { 24 | parent.setConstructorType(ArrayElement.SMALL); 25 | } 26 | } 27 | 28 | if (parent.constructorType() == ArrayElement.SMALL) { 29 | if (0l <= _value.longValue() && _value.longValue() <= 255l) { 30 | return 1; 31 | } else { 32 | parent.setConstructorType(ArrayElement.LARGE); 33 | } 34 | } 35 | 36 | return 8; 37 | 38 | } else { 39 | return 0l == _value.longValue() ? 1 : (1l <= _value.longValue() && _value.longValue() <= 255l) ? 2 : 9; 40 | } 41 | 42 | } 43 | 44 | @Override 45 | public UnsignedLong getValue() { 46 | return _value; 47 | } 48 | 49 | @Override 50 | public Data.DataType getDataType() { 51 | return Data.DataType.ULONG; 52 | } 53 | 54 | @Override 55 | public int encode(ByteBuffer b) { 56 | int size = size(); 57 | if (size > b.remaining()) { 58 | return 0; 59 | } 60 | switch (size) { 61 | case 1: 62 | if (isElementOfArray()) { 63 | b.put((byte) _value.longValue()); 64 | } else { 65 | b.put((byte) 0x44); 66 | } 67 | break; 68 | case 2: 69 | b.put((byte) 0x53); 70 | b.put((byte) _value.longValue()); 71 | break; 72 | case 9: 73 | b.put((byte) 0x80); 74 | case 8: 75 | b.putLong(_value.longValue()); 76 | 77 | } 78 | 79 | return size; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/adhara/interop-service/corda-decoder/src/main/java/io/adhara/poc/amqp/codec/UnsignedIntegerElement.java: -------------------------------------------------------------------------------- 1 | package io.adhara.poc.amqp.codec; 2 | 3 | import io.adhara.poc.amqp.types.UnsignedInteger; 4 | 5 | import java.nio.ByteBuffer; 6 | 7 | class UnsignedIntegerElement extends AtomicElement { 8 | 9 | private final UnsignedInteger _value; 10 | 11 | UnsignedIntegerElement(Element parent, Element prev, UnsignedInteger i) { 12 | super(parent, prev); 13 | _value = i; 14 | } 15 | 16 | @Override 17 | public int size() { 18 | if (isElementOfArray()) { 19 | final ArrayElement parent = (ArrayElement) parent(); 20 | if (parent.constructorType() == ArrayElement.TINY) { 21 | if (_value.intValue() == 0) { 22 | return 0; 23 | } else { 24 | parent.setConstructorType(ArrayElement.SMALL); 25 | } 26 | } 27 | 28 | if (parent.constructorType() == ArrayElement.SMALL) { 29 | if (0 <= _value.intValue() && _value.intValue() <= 255) { 30 | return 1; 31 | } else { 32 | parent.setConstructorType(ArrayElement.LARGE); 33 | } 34 | } 35 | 36 | return 4; 37 | 38 | } else { 39 | return 0 == _value.intValue() ? 1 : (1 <= _value.intValue() && _value.intValue() <= 255) ? 2 : 5; 40 | } 41 | 42 | } 43 | 44 | @Override 45 | public UnsignedInteger getValue() { 46 | return _value; 47 | } 48 | 49 | @Override 50 | public Data.DataType getDataType() { 51 | return Data.DataType.UINT; 52 | } 53 | 54 | @Override 55 | public int encode(ByteBuffer b) { 56 | int size = size(); 57 | if (size > b.remaining()) { 58 | return 0; 59 | } 60 | switch (size) { 61 | case 1: 62 | if (isElementOfArray()) { 63 | b.put((byte) _value.intValue()); 64 | } else { 65 | b.put((byte) 0x43); 66 | } 67 | break; 68 | case 2: 69 | b.put((byte) 0x52); 70 | b.put((byte) _value.intValue()); 71 | break; 72 | case 5: 73 | b.put((byte) 0x70); 74 | case 4: 75 | b.putInt(_value.intValue()); 76 | 77 | } 78 | 79 | return size; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/r3/atomic-swap/corda/evm-interop-workflows/src/main/kotlin/com/r3/corda/evminterop/workflows/swap/RequestNotarisationProofsInitiator.kt: -------------------------------------------------------------------------------- 1 | package com.r3.corda.evminterop.workflows.swap 2 | 3 | import co.paralleluniverse.fibers.Suspendable 4 | import com.r3.corda.evminterop.services.evmInterop 5 | import net.corda.core.crypto.SecureHash 6 | import net.corda.core.flows.* 7 | import net.corda.core.identity.Party 8 | import net.corda.core.utilities.unwrap 9 | 10 | typealias RequestNotarizationProofsInitiator = RequestNotarizationProofs.Initiator 11 | 12 | object RequestNotarizationProofs { 13 | 14 | /** 15 | * Initiating flow which requests validation and attestation of an EVM event from a pool of approved validators. 16 | */ 17 | @StartableByRPC 18 | @InitiatingFlow 19 | class Initiator( 20 | val transactionId: SecureHash, 21 | private val validators: List 22 | ) : FlowLogic>() { 23 | 24 | @Suspendable 25 | override fun call(): List { 26 | return validators.map { validator -> 27 | if(validator.owningKey == ourIdentity.owningKey) { 28 | serviceHub.evmInterop().web3Provider().signData(transactionId.bytes) 29 | } else { 30 | val session = initiateFlow(validator) 31 | session.send(transactionId) 32 | session.receive().unwrap { it } 33 | } 34 | } 35 | } 36 | } 37 | 38 | /** 39 | * Responder flow which validates and attests (signs) an EVM event 40 | */ 41 | @InitiatedBy(Initiator::class) 42 | class Responder(val session: FlowSession) : FlowLogic() { 43 | 44 | @Suspendable 45 | override fun call() { 46 | val transactionId = session.receive().unwrap { it } 47 | 48 | val signature = serviceHub.evmInterop().web3Provider().signData(transactionId.bytes) 49 | 50 | session.send(signature) 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/adhara/interop-service/corda-decoder/src/main/java/io/adhara/poc/amqp/codec/SymbolElement.java: -------------------------------------------------------------------------------- 1 | package io.adhara.poc.amqp.codec; 2 | 3 | import io.adhara.poc.amqp.types.Symbol; 4 | 5 | import java.nio.ByteBuffer; 6 | import java.nio.charset.Charset; 7 | import java.nio.charset.StandardCharsets; 8 | 9 | class SymbolElement extends AtomicElement { 10 | 11 | private static final Charset ASCII = StandardCharsets.US_ASCII; 12 | private final Symbol _value; 13 | 14 | SymbolElement(Element parent, Element prev, Symbol s) { 15 | super(parent, prev); 16 | _value = s; 17 | } 18 | 19 | @Override 20 | public int size() { 21 | final int length = _value.length(); 22 | 23 | if (isElementOfArray()) { 24 | final ArrayElement parent = (ArrayElement) parent(); 25 | 26 | if (parent.constructorType() == ArrayElement.SMALL) { 27 | if (length > 255) { 28 | parent.setConstructorType(ArrayElement.LARGE); 29 | return 4 + length; 30 | } else { 31 | return 1 + length; 32 | } 33 | } else { 34 | return 4 + length; 35 | } 36 | } else { 37 | if (length > 255) { 38 | return 5 + length; 39 | } else { 40 | return 2 + length; 41 | } 42 | } 43 | } 44 | 45 | @Override 46 | public Symbol getValue() { 47 | return _value; 48 | } 49 | 50 | @Override 51 | public Data.DataType getDataType() { 52 | return Data.DataType.SYMBOL; 53 | } 54 | 55 | @Override 56 | public int encode(ByteBuffer b) { 57 | int size = size(); 58 | if (b.remaining() < size) { 59 | return 0; 60 | } 61 | if (isElementOfArray()) { 62 | final ArrayElement parent = (ArrayElement) parent(); 63 | 64 | if (parent.constructorType() == ArrayElement.SMALL) { 65 | b.put((byte) _value.length()); 66 | } else { 67 | b.putInt(_value.length()); 68 | } 69 | } else if (_value.length() <= 255) { 70 | b.put((byte) 0xa3); 71 | b.put((byte) _value.length()); 72 | } else { 73 | b.put((byte) 0xb3); 74 | b.put((byte) _value.length()); 75 | } 76 | b.put(_value.toString().getBytes(ASCII)); 77 | return size; 78 | 79 | } 80 | } 81 | --------------------------------------------------------------------------------