├── .env.dev ├── .github └── workflows │ └── unit_test.yml ├── .gitignore ├── LICENSE ├── README.md ├── composer.json ├── containers └── php │ ├── Dockerfile │ ├── php.ini │ ├── xdebug-linux.ini │ ├── xdebug-mac.ini │ └── xdebug.ini ├── couscous.yml ├── docker-compose.linux.yml ├── docker-compose.mac.yml ├── docker-compose.yml ├── docs ├── README.md ├── address-codec.md ├── binary-codec.md ├── buffer.md ├── client.md ├── core-utilities.md ├── keypairs.md ├── math-utilities.md ├── methods.md ├── networks.md ├── quickstart.md ├── recipes-patterns.md ├── utilities.md └── wallet.md ├── examples ├── client.php ├── custom_currency_codes.php ├── faucet-wallet.php ├── internal │ ├── address-codec.php │ ├── binary-codec.php │ ├── buffer.php │ ├── mock-rippled-curl.php │ └── mock-rippled-method.php ├── payment-with-destination-tag.php ├── payment.php ├── provoke-error.php ├── quickstart │ ├── 0.start-here.php │ ├── 1.get-accounts-send-xrp.php │ ├── 2.create-trustline-send-currency.php │ └── 3.mint-nfts.php ├── rlusd.php ├── token-create.php └── xrpBalance.php ├── phpunit.xml ├── psalm.xml ├── src ├── Client │ └── JsonRpcClient.php ├── Core │ ├── CoreUtilities.php │ ├── Ctid.php │ ├── HashPrefix.php │ ├── MathUtilities.php │ ├── Networks.php │ ├── RippleAddressCodec │ │ ├── AddressCodec.php │ │ ├── BaseX.php │ │ ├── Codec.php │ │ ├── CodecWithXrpAlphabet.php │ │ └── Utils.php │ ├── RippleBinaryCodec │ │ ├── Binary.php │ │ ├── BinaryCodec.php │ │ ├── Definitions │ │ │ ├── Definitions.php │ │ │ ├── FieldHeader.php │ │ │ ├── FieldInfo.php │ │ │ ├── FieldInstance.php │ │ │ └── definitions.json │ │ ├── Serdes │ │ │ ├── BinaryParser.php │ │ │ ├── BinarySerializer.php │ │ │ └── BytesList.php │ │ └── Types │ │ │ ├── AccountId.php │ │ │ ├── Amount.php │ │ │ ├── Blob.php │ │ │ ├── Currency.php │ │ │ ├── Hash.php │ │ │ ├── Hash128.php │ │ │ ├── Hash160.php │ │ │ ├── Hash256.php │ │ │ ├── Issue.php │ │ │ ├── Path.php │ │ │ ├── PathSet.php │ │ │ ├── PathStep.php │ │ │ ├── SerializedType.php │ │ │ ├── StArray.php │ │ │ ├── StObject.php │ │ │ ├── UnsignedInt.php │ │ │ ├── UnsignedInt16.php │ │ │ ├── UnsignedInt32.php │ │ │ ├── UnsignedInt64.php │ │ │ ├── UnsignedInt8.php │ │ │ ├── Vector256.php │ │ │ └── XchainBridge.php │ ├── RippleKeyPairs │ │ ├── AbstractKeyPairService.php │ │ ├── Ed25519KeyPairService.php │ │ ├── KeyPair.php │ │ ├── KeyPairServiceInterface.php │ │ └── Secp256k1KeyPairService.php │ └── Stablecoin.php ├── Exceptions │ ├── ConnectionException.php │ ├── DisconnectedException.php │ ├── NotConnectedException.php │ ├── NotFoundException.php │ ├── ResponseFormatException.php │ ├── RippledException.php │ ├── RippledNotInitializedException.php │ ├── TimeoutException.php │ ├── UnexpectedException.php │ ├── ValidationException.php │ ├── XRPLFaucetException.php │ └── XrplException.php ├── Hooks │ └── hooksDefinitions.json ├── Models │ ├── Account │ │ ├── AccountChannelsRequest.php │ │ ├── AccountChannelsResponse.php │ │ ├── AccountCurrenciesRequest.php │ │ ├── AccountCurrenciesResponse.php │ │ ├── AccountInfoRequest.php │ │ ├── AccountInfoResponse.php │ │ ├── AccountLinesRequest.php │ │ ├── AccountLinesResponse.php │ │ ├── AccountNftsRequest.php │ │ ├── AccountNftsResponse.php │ │ ├── AccountObjectsRequest.php │ │ ├── AccountObjectsResponse.php │ │ ├── AccountOffersRequest.php │ │ ├── AccountOffersResponse.php │ │ ├── AccountTxRequest.php │ │ ├── AccountTxResponse.php │ │ ├── GatewayBalancesRequest.php │ │ ├── GatewayBalancesResponse.php │ │ ├── NorippleCheckRequest.php │ │ └── NorippleCheckResponse.php │ ├── BaseRequest.php │ ├── BaseResponse.php │ ├── Clio │ │ ├── LedgerRequest.php │ │ ├── LedgerResponse.php │ │ ├── NftHistoryRequest.php │ │ ├── NftHistoryResponse.php │ │ ├── NftInfoRequest.php │ │ ├── NftInfoResponse.php │ │ ├── ServerInfoRequest.php │ │ └── ServerInfoResponse.php │ ├── Common │ │ └── Amount.php │ ├── ErrorResponse.php │ ├── Ledger │ │ ├── LedgerClosedRequest.php │ │ ├── LedgerClosedResponse.php │ │ ├── LedgerCurrentRequest.php │ │ ├── LedgerCurrentResponse.php │ │ ├── LedgerDataRequest.php │ │ ├── LedgerDataResponse.php │ │ ├── LedgerEntryRequest.php │ │ ├── LedgerEntryResponse.php │ │ ├── LedgerRequest.php │ │ └── LedgerResponse.php │ ├── PathOrderbook │ │ ├── AmmInfoRequest.php │ │ ├── AmmInfoResponse.php │ │ ├── BookOffersRequest.php │ │ ├── BookOffersResponse.php │ │ ├── DepositAuthorizedRequest.php │ │ ├── DepositAuthorizedResponse.php │ │ ├── NftBuyOffersRequest.php │ │ ├── NftBuyOffersResponse.php │ │ ├── NftSellOffersRequest.php │ │ ├── NftSellOffersResponse.php │ │ ├── README.md │ │ ├── RipplePathFindRequest.php │ │ └── RipplePathFindResponse.php │ ├── PaymentChannel │ │ ├── ChannelAuthorizeRequest.php │ │ ├── ChannelAuthorizeResponse.php │ │ ├── ChannelVerifyRequest.php │ │ └── ChannelVerifyResponse.php │ ├── ServerInfo │ │ ├── FeeRequest.php │ │ ├── FeeResponse.php │ │ ├── ManifestRequest.php │ │ ├── ManifestResponse.php │ │ ├── ServerInfoRequest.php │ │ ├── ServerInfoResponse.php │ │ ├── ServerStateRequest.php │ │ └── ServerStateResponse.php │ ├── Transaction │ │ ├── SubmitMultisignedRequest.php │ │ ├── SubmitMultisignedResponse.php │ │ ├── SubmitRequest.php │ │ ├── SubmitResponse.php │ │ ├── TransactionEntryRequest.php │ │ ├── TransactionEntryResponse.php │ │ ├── TransactionTypes │ │ │ ├── AccountDelete.php │ │ │ ├── AccountSet.php │ │ │ ├── AmmBid.php │ │ │ ├── AmmCreate.php │ │ │ ├── AmmDelete.php │ │ │ ├── AmmDeposit.php │ │ │ ├── AmmVote.php │ │ │ ├── AmmWithdraw.php │ │ │ ├── BaseTransaction.php │ │ │ ├── CheckCash.php │ │ │ ├── CheckChancel.php │ │ │ ├── CheckCreate.php │ │ │ ├── Clawback.php │ │ │ ├── DepositPreauth.php │ │ │ ├── EscrowCancel.php │ │ │ ├── EscrowCreate.php │ │ │ ├── EscrowFinish.php │ │ │ ├── NFTokenAcceptOffer.php │ │ │ ├── NFTokenBurn.php │ │ │ ├── NFTokenCancelOffer.php │ │ │ ├── NFTokenCreateOffer.php │ │ │ ├── NFTokenMint.php │ │ │ ├── OfferCancel.php │ │ │ ├── OfferCreate.php │ │ │ ├── Payment.php │ │ │ ├── PaymentChannelClaim.php │ │ │ ├── PaymentChannelCreate.php │ │ │ ├── PaymentChannelFund.php │ │ │ ├── SetRegularKey.php │ │ │ ├── SignerListSet.php │ │ │ ├── TicketCreate.php │ │ │ └── TrustSet.php │ │ ├── TxHistoryRequest.php │ │ ├── TxHistoryResponse.php │ │ ├── TxRequest.php │ │ └── TxResponse.php │ ├── Utility │ │ ├── JsonRequest.php │ │ ├── JsonResponse.php │ │ ├── PingRequest.php │ │ ├── PingResponse.php │ │ ├── RandomRequest.php │ │ └── RandomResponse.php │ └── Warning.php ├── Polyfill.php ├── Sugar │ ├── autofill.php │ ├── balances.php │ ├── fundWallet.php │ ├── getFeeXrp.php │ ├── getTransactions.php │ ├── submit.php │ └── xrpConversion.php ├── Utils │ ├── Hashes │ │ └── HashLedger.php │ └── Utilities.php └── Wallet │ ├── DefaultFaucets.php │ └── Wallet.php ├── tests ├── Client │ └── JsonRpcClientTest.php ├── Core │ ├── CtidTest.php │ ├── RippleAddressCodec │ │ ├── AddressCodecTest.php │ │ ├── BaseXTest.php │ │ └── fixtures.json │ ├── RippleBinaryCodec │ │ ├── BinaryCodecTest.php │ │ ├── BinaryParserTest.php │ │ ├── Types │ │ │ ├── AccountIdTest.php │ │ │ ├── AmountTest.php │ │ │ ├── BlobTest.php │ │ │ ├── CurrencyTest.php │ │ │ ├── HashTest.php │ │ │ ├── IssueTest.php │ │ │ ├── PathSetTest.php │ │ │ ├── PathStepTest.php │ │ │ ├── PathTest.php │ │ │ ├── StArrayTest.php │ │ │ ├── StObjectTest.php │ │ │ ├── UIntTest.php │ │ │ ├── Vector256Test.php │ │ │ ├── XchainBridgeTest.php │ │ │ └── fixtures.json │ │ └── fixtures.json │ ├── RippleKeyPairs │ │ ├── KeyPairTest.php │ │ └── fixtures.json │ └── UtilitiesTest.php ├── Fixtures │ ├── Requests │ │ ├── getOrderbook.json │ │ ├── getOrderbookWithXrp.json │ │ ├── hashLedger.json │ │ ├── hashLedgerTransactions.json │ │ ├── sign.json │ │ ├── signAs.json │ │ ├── signEscrow.json │ │ ├── signPaymentChannelClaim.json │ │ └── signTicket.json │ └── Responses │ │ ├── generateAddress.json │ │ ├── generateXAddress.json │ │ ├── getAccountObjects.json │ │ ├── getBalances.json │ │ ├── getLedgerFull.json │ │ ├── getOrderbook.json │ │ ├── getOrderbookWithXrp.json │ │ ├── getServerInfo.json │ │ ├── sign.json │ │ ├── signAs.json │ │ ├── signEscrow.json │ │ ├── signPaymentChannelClaim.json │ │ └── signTicket.json ├── Integration │ ├── BasicIntegrationTest.php │ └── FundWalletTest.php ├── MockRippled │ ├── Fixtures │ │ ├── Requests │ │ │ └── serverInfo.json │ │ └── Responses │ │ │ └── serverInfo.json │ ├── MockRippledResponse.php │ └── MockRippledServer.php ├── Models │ └── Transaction │ │ └── BaseTransactionTest.php ├── PolyfillTest.php ├── Sugar │ ├── AutofillTest.php │ ├── BalancesTest.php │ └── XrpConversionTest.php ├── Utils │ └── UtilitiesTest.php └── Wallet │ └── WalletTest.php └── website ├── css └── highlight.css ├── default.twig ├── documentation.twig ├── fonts ├── FontAwesome.otf ├── fontawesome-webfont.eot ├── fontawesome-webfont.svg ├── fontawesome-webfont.ttf └── fontawesome-webfont.woff └── js ├── bootstrap.min.js ├── highlight.min.js └── jquery.min.js /.env.dev: -------------------------------------------------------------------------------- 1 | ##Testnet Servers 2 | # WebSocket 3 | # wss://s.altnet.rippletest.net:51233 4 | # 5 | # JSON-RPC 6 | # https://s.altnet.rippletest.net:51234 7 | 8 | ##Devnet Servers 9 | # WebSocket 10 | # wss://s.devnet.rippletest.net:51233 11 | # 12 | # JSON-RPC 13 | # https://s.devnet.rippletest.net:51234 14 | 15 | ##Devnet Servers 16 | # WebSocket 17 | # wss://xls20-sandbox.rippletest.net:51233 18 | # 19 | # JSON-RPC 20 | # http://xls20-sandbox.rippletest.net:51234 21 | 22 | ##local Servers 23 | # WebSocket 24 | # wss://localhost:6006 25 | # 26 | # JSON-RPC 27 | # http://localhost:5005 28 | 29 | 30 | APP_ENV=dev 31 | 32 | -------------------------------------------------------------------------------- /.github/workflows/unit_test.yml: -------------------------------------------------------------------------------- 1 | name: Unit Test (PHPUnit) 2 | on: push 3 | 4 | jobs: 5 | phpunit: 6 | runs-on: ubuntu-latest 7 | 8 | steps: 9 | - uses: actions/checkout@v3 10 | 11 | - name: Setup PHP 12 | uses: shivammathur/setup-php@v2 13 | with: 14 | php-version: '8.1' 15 | tools: composer, phpunit 16 | extensions: ds, gmp, sockets 17 | coverage: none 18 | # 19 | - name: Install composer dependencies 20 | uses: php-actions/composer@v6 21 | with: 22 | php_version: "8.1" 23 | php_extensions: gmp sockets bcmath 24 | version: latest 25 | 26 | - name: Run PHPUnit 27 | run: vendor/bin/phpunit ./tests -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /.idea 2 | 3 | /.env 4 | /composer.lock 5 | /docker-compose.override.yml 6 | 7 | /_java/ 8 | /_js/ 9 | /_py/ 10 | /_private_scripts/ 11 | /examples/quickstart/.env 12 | /vendor/ 13 | 14 | /.phpunit.result.cache 15 | 16 | # Documentation 17 | /.couscous/ 18 | /website/bower_components/ 19 | /website/css/all.min.css -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2022, Alexander Busse | Hardcastle Technologies 2 | 3 | Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, 4 | provided that the above copyright notice and this permission notice appear in all copies. 5 | 6 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE 7 | INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE 8 | FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 9 | LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 10 | OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hardcastle/xrpl_php", 3 | "description": "PHP Client for the XRP Ledger", 4 | "minimum-stability": "stable", 5 | "license": "ISC", 6 | "authors": [ 7 | { 8 | "name": "Alexander Busse", 9 | "email": "alexander.busse@posteo.net" 10 | } 11 | ], 12 | "config": { 13 | "optimize-autoloader": true, 14 | "platform": { 15 | "php": "8.1" 16 | } 17 | }, 18 | "autoload": { 19 | "psr-4": { 20 | "Hardcastle\\XRPL_PHP\\": "src/" 21 | }, 22 | "files": [ 23 | "src/Polyfill.php", 24 | "src/Sugar/autofill.php", 25 | "src/Sugar/balances.php", 26 | "src/Sugar/fundWallet.php", 27 | "src/Sugar/getFeeXrp.php", 28 | "src/Sugar/submit.php", 29 | "src/Sugar/xrpConversion.php" 30 | ] 31 | }, 32 | "autoload-dev": { 33 | "psr-4": { 34 | "Hardcastle\\XRPL_PHP\\Test\\": "tests/" 35 | } 36 | }, 37 | "require": { 38 | "brick/math": "^0.11|^0.12", 39 | "codedungeon/php-cli-colors": "^1.12", 40 | "ext-bcmath": "*", 41 | "guzzlehttp/guzzle": "^7.4", 42 | "php-ds/php-ds": "^1.4", 43 | "simplito/elliptic-php": "^1.0.12", 44 | "simplito/bn-php": "^1.1.4", 45 | "hardcastle/buffer": "^0.2.0" 46 | }, 47 | "require-dev": { 48 | "phpunit/phpunit": "^10.3.1", 49 | "vimeo/psalm": "^5.14", 50 | "donatj/mock-webserver": "^2.6.2" 51 | }, 52 | "scripts": { 53 | "psalm": "vendor/bin/psalm --config=psalm.xml" 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /containers/php/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM php:8.1.4-fpm-alpine 2 | 3 | RUN apk update \ 4 | && apk upgrade \ 5 | && apk add gmp-dev \ 6 | && apk add --no-cache bash $PHPIZE_DEPS \ 7 | && docker-php-ext-install gmp \ 8 | && docker-php-ext-install sockets \ 9 | && pecl install xdebug-3.1.3 \ 10 | && pecl install ds 11 | 12 | COPY --from=composer /usr/bin/composer /usr/bin/composer 13 | 14 | WORKDIR /app -------------------------------------------------------------------------------- /containers/php/php.ini: -------------------------------------------------------------------------------- 1 | extension=ds.so 2 | 3 | -------------------------------------------------------------------------------- /containers/php/xdebug-linux.ini: -------------------------------------------------------------------------------- 1 | ;zend_extension=xdebug.so 2 | xdebug.mode=debug 3 | xdebug.start_with_request=yes 4 | xdebug.client_host=172.18.0.1 5 | xdebug.client_port=9003 -------------------------------------------------------------------------------- /containers/php/xdebug-mac.ini: -------------------------------------------------------------------------------- 1 | zend_extension=xdebug.so 2 | xdebug.mode=debug 3 | xdebug.start_with_request=yes 4 | xdebug.client_host=host.docker.internal 5 | xdebug.client_port=9090 -------------------------------------------------------------------------------- /containers/php/xdebug.ini: -------------------------------------------------------------------------------- 1 | zend_extension=xdebug.so 2 | xdebug.mode=debug 3 | xdebug.start_with_request=yes 4 | xdebug.client_host=host.docker.internal 5 | xdebug.client_port=9090 6 | -------------------------------------------------------------------------------- /couscous.yml: -------------------------------------------------------------------------------- 1 | baseUrl: https://alexanderbuzz.github.io/xrpl-php-docs/ 2 | 3 | include: 4 | - docs 5 | 6 | menu: 7 | items: 8 | introduction: 9 | section: Concepts 10 | items: 11 | quickstart: 12 | text: Quickstart 13 | url: quickstart.html 14 | wallet: 15 | text: Wallet 16 | url: wallet.html 17 | client: 18 | text: JSON RPC Client 19 | url: client.html 20 | methods: 21 | text: Client Methods 22 | url: methods.html 23 | core: 24 | section: Core 25 | items: 26 | address-codec: 27 | text: AddressCodec 28 | url: address-codec.html 29 | binary-codec: 30 | text: BinaryCodec 31 | url: binary-codec.html 32 | keypairs: 33 | text: Keypairs 34 | url: keypairs.html 35 | buffer: 36 | text: Buffer 37 | url: buffer.html 38 | ctid: 39 | text: CTID 40 | url: ctid.html 41 | networks: 42 | text: Networks 43 | url: networks.html 44 | utilities: 45 | section: Utilities 46 | items: 47 | core-utilities: 48 | text: Core Utilities 49 | url: core-utilities.html 50 | math-utilities: 51 | text: Math Utilities 52 | url: math-utilities.html 53 | utilities: 54 | text: Utilities 55 | url: utilities.html -------------------------------------------------------------------------------- /docker-compose.linux.yml: -------------------------------------------------------------------------------- 1 | # Use this as docker-compose.override.yml if you use Linux 2 | services: 3 | php: 4 | volumes: 5 | - .:/app 6 | - ~/.composer/cache:/.composer/cache 7 | - ./containers/php/php.ini:/usr/local/etc/php/conf.d/docker-php.ini 8 | - ./containers/php/php.ini:/usr/local/etc/php/conf.d/docker-php.ini 9 | tmpfs: 10 | - /tmp:mode=1777 11 | user: "1000:1000" 12 | -------------------------------------------------------------------------------- /docker-compose.mac.yml: -------------------------------------------------------------------------------- 1 | # Use this as docker-compose.override.yml if you use Mac 2 | services: 3 | php: 4 | volumes: 5 | - .:/app 6 | - ~/.composer/cache:/.composer/cache 7 | - ./containers/php/xdebug.ini:/usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini 8 | - ./containers/php/php.ini:/usr/local/etc/php/conf.d/docker-php.ini 9 | user: "501:20" 10 | environment: 11 | PHP_IDE_CONFIG: "serverName=docker" -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | services: 2 | php: 3 | build: 4 | context: containers/php 5 | volumes: 6 | - .:/app 7 | 8 | rippled: 9 | container_name: rippled 10 | image: natenichols/rippled-standalone:latest 11 | ports: 12 | - "5005:5005" 13 | - "6006:6006" -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Documentation index 3 | --- 4 | 5 | ## Introduction 6 | 7 | XRPL_PHP is the PHP SDK for the [XRPL | XRP Ledger](https://xrpl.org/). The XRP Ledger (XRPL) is a decentralized, 8 | public blockchain led by a global community of businesses and developers looking to solve problems and create value. 9 | 10 | Proven reliable over more than a decade of error-free functioning, the XRPL offers streamlined development, 11 | low transaction costs, high performance, and sustainability. So you can build with confidence–and move your most critical projects forward. 12 | 13 | ## Getting Started 14 | 15 | To get a quick overview on how to use XRPL_PHP, just go to the [Quickstart](quickstart.md) page. 16 | 17 | For in-depth documentation, you can refer to the following pages: 18 | 19 | ### Concepts 20 | 21 | * [Wallet](wallet.md) 22 | * [JSON RPC Client](client.md) 23 | * [Client Methods](methods.md) 24 | * [Recipes & Patterns](recipes-patterns.md) 25 | 26 | The documentation is structured in a consecutive way. By just skimming each page in order, you will get a birds eye view 27 | of all the available building blocks and how to make them interact with each other. 28 | 29 | ### License 30 | 31 | PHP-XRPL is released under the ISC license. 32 | 33 | This documentation is also embedded in [XRPL_PHP's git repository](https://github.com/AlexanderBuzz/XRPL_PHP/tree/master/docs) 34 | so you can read it offline (in the `docs/` folder). -------------------------------------------------------------------------------- /docs/address-codec.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: documentation 3 | title: Address Codec 4 | current_menu: address-codec 5 | --- -------------------------------------------------------------------------------- /docs/binary-codec.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: documentation 3 | title: Binary Codec 4 | current_menu: binary-codec 5 | --- -------------------------------------------------------------------------------- /docs/buffer.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: documentation 3 | title: Buffer 4 | current_menu: buffer 5 | --- -------------------------------------------------------------------------------- /docs/core-utilities.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: documentation 3 | title: Core Utilities 4 | current_menu: core-utilities 5 | --- -------------------------------------------------------------------------------- /docs/keypairs.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: documentation 3 | title: JSON RPC Client 4 | current_menu: client 5 | --- -------------------------------------------------------------------------------- /docs/math-utilities.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: documentation 3 | title: Math Utilities 4 | current_menu: math-utilities 5 | --- -------------------------------------------------------------------------------- /docs/methods.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: documentation 3 | title: Methods 4 | current_menu: methods 5 | --- 6 | 7 | # Request and Response Methods 8 | 9 | -------------------------------------------------------------------------------- /docs/networks.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: documentation 3 | title: Networks 4 | current_menu: networks 5 | --- -------------------------------------------------------------------------------- /docs/recipes-patterns.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: documentation 3 | title: Recipes and Patterns 4 | current_menu: recipes-patterns 5 | --- -------------------------------------------------------------------------------- /docs/utilities.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: documentation 3 | title: Utilities 4 | current_menu: utilities 5 | --- -------------------------------------------------------------------------------- /examples/client.php: -------------------------------------------------------------------------------- 1 | syncRequest($pingRequest); 33 | $result = $pingResponse->getResult(); 34 | print_r($result); 35 | 36 | // Perform a "raw" request 37 | $body = json_encode([ 38 | "method" => "server_info", 39 | "params" => [ 40 | ["api_version" => 1] 41 | ] 42 | ]); 43 | $response = $client->rawSyncRequest('POST', '', $body); 44 | $content = $response->getBody()->getContents(); 45 | print_r($content); -------------------------------------------------------------------------------- /examples/custom_currency_codes.php: -------------------------------------------------------------------------------- 1 | Hash: " . $customCurrency . ' -> ' . $hash . PHP_EOL); 12 | 13 | $currencyBacktest = CoreUtilities::decodeCustomCurrency($hash); 14 | 15 | print_r("Hash -> Currency: ". $hash . ' -> ' . $currencyBacktest . PHP_EOL); -------------------------------------------------------------------------------- /examples/faucet-wallet.php: -------------------------------------------------------------------------------- 1 | getAddress() . PHP_EOL); 17 | print_r('Wallet seed: ' . $wallet->getSeed()); -------------------------------------------------------------------------------- /examples/internal/address-codec.php: -------------------------------------------------------------------------------- 1 | classicAddressToXAddress($input, 4294967295); 15 | print_r("Encoded Address: " . $encoded . PHP_EOL . PHP_EOL); 16 | 17 | $input = 'r3SVzk8ApofDJuVBPKdmbbLjWGCCXpBQ2g'; 18 | $expected = 'T7oKJ3q7s94kDH6tpkBowhetT1JKfcfdSCmAXbS75iATyLD'; 19 | print_r("Input: " . $input . PHP_EOL . "Expected: " . $expected . PHP_EOL); 20 | $encoded = $codec->classicAddressToXAddress($input, 123, true); 21 | print_r("Testnet Encoded Address: " . $encoded . PHP_EOL . PHP_EOL); 22 | 23 | $input = 'XVLhHMPHU98es4dbozjVtdWzVrDjtV18pX8yuPT7y4xaEHi'; 24 | $expected = [ 25 | "classicAddress" => "rGWrZyQqhTp9Xu7G5Pkayo7bXjH4k4QYpf", 26 | "tag" => 4294967295, 27 | "test" => false 28 | ]; 29 | print_r("Input: " . $input . PHP_EOL . "Expected: " . print_r($expected, true)); 30 | $decoded = $codec->xAddressToClassicAddress($input); 31 | print_r("Decoded Address: " . print_r($decoded, true) . PHP_EOL . PHP_EOL); 32 | 33 | 34 | $valid = $codec->isValidXAddress('XVLhHMPHU98es4dbozjVtdWzVrDjtV18pX8yuPT7y4xaEHi'); 35 | //should be: 1 36 | print_r("Test Address validity: " . $valid . PHP_EOL); -------------------------------------------------------------------------------- /examples/internal/binary-codec.php: -------------------------------------------------------------------------------- 1 | "Payment", 12 | "Flags" => 2147483648, 13 | "Sequence" => 1, 14 | "Account" => "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ", 15 | "Destination" => "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" 16 | ]; 17 | */ 18 | 19 | /* 20 | print_r('ripple-binary-codec decode example, HEX string to JSON object' . PHP_EOL. PHP_EOL); 21 | 22 | $taArray = [ 23 | "TransactionType" => "Payment", 24 | "Sequence" => 1, 25 | "Flags" => 2147483648 26 | ]; 27 | $encodedTaArray = "12000022800000002400000001"; 28 | 29 | $decodedTaArray = $codec->decode($encodedTaArray); 30 | 31 | print_r("Input: " . $encodedTaArray . PHP_EOL . "Expected: " . print_r($taArray, true)); 32 | $decoded = $codec->decode($encodedTaArray); 33 | print_r("Decoded Transaction: " . print_r($decoded, true) . PHP_EOL . PHP_EOL); 34 | */ 35 | 36 | //$encodedTa3 = "120000"; //TransactionType: Payment 37 | //$encodedTa3 = "120001";//TransactionType: EscrowCreate 38 | 39 | //$decoded = $codec->decode($encodedTaArray); 40 | //$decoded = $codec->decode($taArray); 41 | //print_r($decoded); 42 | 43 | $memoArray = [ 44 | "MemoType" => "687474703A2F2F6578616D706C652E636F6D2F6D656D6F2F67656E65726963", 45 | "MemoData" => "72656E74" 46 | ]; 47 | 48 | $encoded = $codec->encode($memoArray); 49 | 50 | print_r($encoded); 51 | 52 | -------------------------------------------------------------------------------- /examples/internal/buffer.php: -------------------------------------------------------------------------------- 1 | start(); 9 | 10 | $url = $server->getServerRoot() . '/endpoint?get=foobar'; 11 | 12 | echo "Requesting: $url\n\n"; 13 | echo file_get_contents($url); 14 | 15 | $ch = curl_init(); 16 | 17 | // Return Page contents. 18 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 19 | 20 | // Grab URL and pass it to the variable 21 | curl_setopt($ch, CURLOPT_URL, $url); 22 | 23 | $result = curl_exec($ch); 24 | 25 | echo $result; -------------------------------------------------------------------------------- /examples/internal/mock-rippled-method.php: -------------------------------------------------------------------------------- 1 | start(); 12 | 13 | $body1 = json_encode([ 14 | "method" => "server_info", 15 | "params" => [ 16 | ["api_version" => 1] 17 | ] 18 | ]); 19 | 20 | $body2 = json_encode([ 21 | "method" => "server_info", 22 | "params" => [ 23 | ["api_version" => 2] 24 | ] 25 | ]); 26 | $rippledRes1 = new MockRippledResponse($body1); 27 | $rippledRes2 = new MockRippledResponse($body2); 28 | 29 | print_r(PHP_EOL . "RippledRes1:" . PHP_EOL); 30 | print_r($rippledRes1->getRef() . PHP_EOL); 31 | print_r(PHP_EOL . "RippledRes2:" . PHP_EOL); 32 | print_r($rippledRes2->getRef() . PHP_EOL); 33 | 34 | $url = $server->setResponseOfPath( 35 | $rippledRes1->getRef(), 36 | $rippledRes1 37 | ); 38 | echo $server->getUrlOfResponse($rippledRes1) . PHP_EOL . PHP_EOL; 39 | 40 | $url = $server->setResponseOfPath( 41 | $rippledRes2->getRef(), 42 | $rippledRes2 43 | ); 44 | echo $server->getUrlOfResponse($rippledRes2) . PHP_EOL . PHP_EOL; 45 | 46 | $client = new JsonRpcClient($server->getServerRoot()); 47 | 48 | $response1 = $client->rawSyncRequest('POST', $rippledRes1->getRef(), $body1); 49 | $content = $response1->getBody()->getContents(); 50 | print_r($content . PHP_EOL); 51 | 52 | $response1 = $client->rawSyncRequest('POST', $rippledRes2->getRef(), $body2); 53 | $content = $response1->getBody()->getContents(); 54 | print_r($content . PHP_EOL); 55 | 56 | $server->stop(); -------------------------------------------------------------------------------- /examples/payment-with-destination-tag.php: -------------------------------------------------------------------------------- 1 | "Payment", 22 | "Account" => $standbyWallet->getAddress(), 23 | "Amount" => xrpToDrops($xrpAmount), 24 | "Destination" => $operationalWallet->getAddress(), 25 | "DestinationTag" => 1937215245 26 | ]; 27 | $autofilledTx = $client->autofill($tx); 28 | print_r($tx); 29 | print_r(PHP_EOL. PHP_EOL); 30 | print_r($autofilledTx); 31 | $signedTx = $standbyWallet->sign($autofilledTx); 32 | 33 | $txResponse = $client->submitAndWait($signedTx['tx_blob']); 34 | $result = $txResponse->getResult(); 35 | if ($result['meta']['TransactionResult'] === 'tecUNFUNDED_PAYMENT') { 36 | print_r(Color::RED . "Error: The sending account is unfunded! TxHash: " . Color::RESET . "{$result['hash']}" . PHP_EOL . PHP_EOL); 37 | } else { 38 | print_r(Color::GREEN . "Token payment done! TxHash: " . Color::WHITE . "{$result['hash']}" . PHP_EOL . PHP_EOL); 39 | } 40 | 41 | print_r(Color::RESET . "You can check wallets/accounts and transactions on https://test.bithomp.com" . PHP_EOL . PHP_EOL); 42 | -------------------------------------------------------------------------------- /examples/provoke-error.php: -------------------------------------------------------------------------------- 1 | "server_info", //We provoke an error by leaving out the server method, so rippled does not know what to do 16 | "params" => [ 17 | ["api_version" => 1] 18 | ] 19 | ]); 20 | 21 | try { 22 | $response = $client->rawSyncRequest('POST', '', $faultyBody); 23 | } catch (Exception $e) { 24 | $response = $e->getResponse(); 25 | $statusCode = $response->getStatusCode(); 26 | $reason = $response->getReasonPhrase(); 27 | $error = trim($response->getBody()->getContents()); 28 | $xrplErrorResponse = new ErrorResponse(null, $statusCode, $error); 29 | 30 | print_r('--- Rippled ErrorResponse: ---'); 31 | print_r('--- Status: ' . $xrplErrorResponse->getStatusCode() . ' Error: ' . $xrplErrorResponse->getError() . ' ---' . PHP_EOL); 32 | } 33 | 34 | -------------------------------------------------------------------------------- /examples/quickstart/0.start-here.php: -------------------------------------------------------------------------------- 1 | fundWallet(); 21 | print_r(Color::GREEN . "Created wallet - address: " . Color::WHITE . "{$wallet->getAddress()} " . Color::GREEN . "seed: " . Color::WHITE . "{$wallet->getSeed()}" . PHP_EOL); 22 | 23 | print_r(Color::YELLOW . "Minting NFT, please wait..." . PHP_EOL); 24 | 25 | $tokenUrl = 'ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf4dfuylqabf3oclgtqy55fbzdi'; // Sample URL 26 | $flags = 8; // Sets the tsTransferable flag 27 | $transferFee = 1000; // 1% Fee 28 | 29 | $tx = [ 30 | "TransactionType" => "NFTokenMint", 31 | "Account" => $wallet->getAddress(), 32 | "URI" => Utilities::convertStringToHex($tokenUrl), 33 | "Flags" => $flags, 34 | "TransferFee" => $transferFee, 35 | "NFTokenTaxon" => 0 //Required, but if you have no use for it, set to zero. 36 | ]; 37 | $preparedTx = $client->autofill($tx); 38 | $signedTx = $wallet->sign($preparedTx); 39 | $txResult = $client->submitAndWait($signedTx['tx_blob']); 40 | print_r(Color::GREEN . "Non fungible token minted!: TxHash: " . Color::WHITE . "{$txResult->getResult()['hash']}" . PHP_EOL . PHP_EOL); 41 | 42 | print_r(Color::RESET . "You can check wallets/accounts and transactions on https://test.bithomp.com" . PHP_EOL . PHP_EOL); 43 | 44 | // print_r(Color::RESET . "Performing AccountNftRequest:" . PHP_EOL); 45 | // $nftRequest = new AccountNftsRequest(account: $wallet->getAddress()); 46 | // $nftResponse = $client->request($nftRequest)->wait(); 47 | // print_r($nftResponse->getResult()); 48 | -------------------------------------------------------------------------------- /examples/rlusd.php: -------------------------------------------------------------------------------- 1 | fundWallet(); 21 | print_r(Color::GREEN . "Created wallet - address: " . Color::WHITE . "{$wallet->getAddress()} " . Color::GREEN . "seed: " . Color::WHITE . "{$wallet->getSeed()}" . PHP_EOL); 22 | 23 | 24 | print_r(Color::YELLOW . "Creating RLUSD trust line, please wait..." . PHP_EOL); 25 | $trustSetTx = [ 26 | "TransactionType" => "TrustSet", 27 | "Account" => $wallet->getAddress(), 28 | "LimitAmount" => Stablecoin::getRLUSDAmount(NETWORK, '10000') 29 | ]; 30 | $trustSetPreparedTx = $client->autofill($trustSetTx); 31 | $signedTx = $wallet->sign($trustSetPreparedTx); 32 | $trustSetResponse = $client->submitAndWait($signedTx['tx_blob']); 33 | print_r(Color::GREEN . "Trust line created! TxHash: " . Color::WHITE . "{$trustSetResponse->getResult()['hash']}" . PHP_EOL); 34 | -------------------------------------------------------------------------------- /examples/xrpBalance.php: -------------------------------------------------------------------------------- 1 | getBody()); 24 | $response = $client->syncRequest($xrpBalanceRequest, true); 25 | 26 | $content = $response->getBody()->getContents(); 27 | $json = json_decode($content, true); 28 | 29 | print_r(PHP_EOL); 30 | print_r("XRP Balance for Wallet {$testnetAccount} is {$json['result']['account_data']['Balance']} XRP"); 31 | print_r(PHP_EOL); 32 | 33 | $req = new AccountTxRequest($testnetAccount); 34 | $res = $client->syncRequest($req, true); 35 | 36 | $content = $response->getBody()->getContents(); 37 | $json = json_decode($content, true); 38 | 39 | print_r(PHP_EOL); 40 | print_r($json); 41 | print_r(PHP_EOL); -------------------------------------------------------------------------------- /phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | tests 10 | 11 | 12 | -------------------------------------------------------------------------------- /psalm.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/Core/HashPrefix.php: -------------------------------------------------------------------------------- 1 | bufferArray = []; 25 | } 26 | 27 | public function getLength(): int 28 | { 29 | return count($this->bufferArray); 30 | } 31 | 32 | public function grab(int $index): Buffer 33 | { 34 | return $this->bufferArray[$index]; //TODO: This is optimistic :) 35 | } 36 | 37 | /** 38 | * @psalm-param 0 $byteIndex 39 | */ 40 | public function deepGrab(int $bufferIndex, int $byteIndex): int 41 | { 42 | return $this->bufferArray[$bufferIndex][$byteIndex]; //TODO: This is very optimistic :) 43 | } 44 | 45 | public function prepend(Buffer $prefix): BytesList 46 | { 47 | $this->bufferArray = array_merge([$prefix], $this->bufferArray); 48 | 49 | return $this; 50 | } 51 | 52 | public function push(Buffer $bytesArg): BytesList 53 | { 54 | $this->bufferArray[] = $bytesArg; 55 | 56 | return $this; 57 | } 58 | 59 | public function replace(int $index, Buffer $newElement): void 60 | { 61 | $this->bufferArray[$index] =$newElement; 62 | } 63 | 64 | public function toBytes(): Buffer 65 | { 66 | $tempArray = []; 67 | 68 | foreach ($this->bufferArray as $buffer) { 69 | $tempArray = array_merge($tempArray, $buffer->toArray()); 70 | } 71 | 72 | return Buffer::from($tempArray); 73 | } 74 | 75 | 76 | } -------------------------------------------------------------------------------- /src/Core/RippleBinaryCodec/Types/AccountId.php: -------------------------------------------------------------------------------- 1 | read(static::$width)); 33 | } 34 | 35 | public static function fromJson(string $serializedJson): SerializedType 36 | { 37 | if ($serializedJson === '') { 38 | return new AccountId(); 39 | } 40 | 41 | $isHex = (preg_match(self::HEX_REGEX, $serializedJson) === 1); 42 | 43 | if ($isHex) { 44 | return new AccountId(Buffer::from($serializedJson)); 45 | } 46 | 47 | $addressCodec = new AddressCodec(); 48 | 49 | return new AccountId($addressCodec->decodeAccountId($serializedJson)); 50 | } 51 | 52 | public function toJson(): array|string|int 53 | { 54 | $addressCodec = new AddressCodec(); 55 | 56 | return $addressCodec->encodeAccountId($this->bytes); 57 | } 58 | } -------------------------------------------------------------------------------- /src/Core/RippleBinaryCodec/Types/Blob.php: -------------------------------------------------------------------------------- 1 | getSize(); 35 | } 36 | return new Blob($parser->read($lengthHint)); 37 | } 38 | 39 | public static function fromJson(string $serializedJson): SerializedType 40 | { 41 | return new Blob(Buffer::from($serializedJson)); 42 | } 43 | } -------------------------------------------------------------------------------- /src/Core/RippleBinaryCodec/Types/Hash.php: -------------------------------------------------------------------------------- 1 | getLength() !== $width) { 26 | throw new \Exception("Invalid hash length " . $bytes->getLength()); 27 | } 28 | 29 | static::$width = $width; 30 | } 31 | 32 | public function getWidth(): int 33 | { 34 | return static::$width; 35 | } 36 | 37 | } -------------------------------------------------------------------------------- /src/Core/RippleBinaryCodec/Types/Hash128.php: -------------------------------------------------------------------------------- 1 | read(static::$width)); 34 | } 35 | 36 | public static function fromJson(string $serializedJson): SerializedType 37 | { 38 | return new Hash128(Buffer::from($serializedJson)); 39 | } 40 | } -------------------------------------------------------------------------------- /src/Core/RippleBinaryCodec/Types/Hash160.php: -------------------------------------------------------------------------------- 1 | read(static::$width)); 34 | } 35 | 36 | public static function fromJson(string $serializedJson): SerializedType 37 | { 38 | return new Hash160(Buffer::from($serializedJson)); 39 | } 40 | } -------------------------------------------------------------------------------- /src/Core/RippleBinaryCodec/Types/Hash256.php: -------------------------------------------------------------------------------- 1 | read(static::$width)); 34 | } 35 | 36 | public static function fromJson(string $serializedJson): SerializedType 37 | { 38 | return new Hash256(Buffer::from($serializedJson)); 39 | } 40 | } -------------------------------------------------------------------------------- /src/Core/RippleBinaryCodec/Types/UnsignedInt.php: -------------------------------------------------------------------------------- 1 | value = BigInteger::of(0); 32 | } else { 33 | $this->value = BigInteger::fromBase($bytes->toString(), 16); 34 | } 35 | } 36 | 37 | /** 38 | * 39 | * 40 | * @return Buffer 41 | */ 42 | public function toBytes(): Buffer 43 | { 44 | return $this->bytes; 45 | } 46 | 47 | /** 48 | * 49 | * @return string 50 | */ 51 | public function toHex(): string 52 | { 53 | return strtoupper($this->toBytes()->toString()); 54 | } 55 | 56 | /** 57 | * 58 | * @return array|string|int 59 | */ 60 | public function toJson(): array|string|int 61 | { 62 | return $this->valueOf(); 63 | } 64 | 65 | /** 66 | * 67 | * @return int|string 68 | */ 69 | public abstract function valueOf(): int|string; 70 | } -------------------------------------------------------------------------------- /src/Core/RippleBinaryCodec/Types/UnsignedInt16.php: -------------------------------------------------------------------------------- 1 | readUInt16(); 22 | return new UnsignedInt16($bytes); 23 | } 24 | 25 | public static function fromJson(string|int $serializedJson): SerializedType 26 | { 27 | if (is_string($serializedJson)) { 28 | $serializedJson = (int) json_decode($serializedJson); 29 | } 30 | 31 | return new UnsignedInt16(Buffer::from(dechex($serializedJson))); 32 | } 33 | 34 | public function toBytes(): Buffer 35 | { 36 | $hexStr = $this->value->toBase(16); 37 | $uint16HexStr = str_pad($hexStr, 4, "0", STR_PAD_LEFT); 38 | 39 | return Buffer::from($uint16HexStr, 'hex'); 40 | } 41 | 42 | public function valueOf(): int|string 43 | { 44 | return $this->value->toInt(); 45 | } 46 | } -------------------------------------------------------------------------------- /src/Core/RippleBinaryCodec/Types/UnsignedInt32.php: -------------------------------------------------------------------------------- 1 | readUInt32(); 22 | return new UnsignedInt32($bytes ); 23 | } 24 | 25 | public static function fromJson(string|int $serializedJson): SerializedType 26 | { 27 | if (is_string($serializedJson)) { 28 | $serializedJson = (int) json_decode($serializedJson); 29 | } 30 | 31 | return new UnsignedInt32(Buffer::from(dechex($serializedJson))); 32 | } 33 | 34 | public function toBytes(): Buffer 35 | { 36 | $hexStr = $this->value->toBase(16); 37 | $uint32HexStr = str_pad($hexStr, 8, "0", STR_PAD_LEFT); 38 | 39 | return Buffer::from($uint32HexStr, 'hex'); 40 | } 41 | 42 | public function valueOf(): int|string 43 | { 44 | return $this->value->toInt(); 45 | } 46 | } -------------------------------------------------------------------------------- /src/Core/RippleBinaryCodec/Types/UnsignedInt64.php: -------------------------------------------------------------------------------- 1 | readUInt64()->toString(); 22 | return new UnsignedInt64(Buffer::from($hexValue, 'hex')); 23 | } 24 | 25 | public static function fromJson(string $serializedJson): UnsignedInt64 26 | { 27 | $bigInteger = BigInteger::fromBase($serializedJson, 10); 28 | return new UnsignedInt64(Buffer::from($bigInteger->toBase(16))); 29 | } 30 | 31 | public function toBytes(): Buffer 32 | { 33 | $hexStr = $this->value->toBase(16); 34 | $uint64HexStr = str_pad($hexStr, 16, "0", STR_PAD_LEFT); 35 | 36 | return Buffer::from($uint64HexStr, 'hex'); 37 | } 38 | 39 | public function valueOf(): int|string 40 | { 41 | return $this->value->toBase(10); 42 | } 43 | } -------------------------------------------------------------------------------- /src/Core/RippleBinaryCodec/Types/UnsignedInt8.php: -------------------------------------------------------------------------------- 1 | readUInt8(); 24 | return new UnsignedInt8($bytes ); 25 | } 26 | 27 | public static function fromJson(string|int $serializedJson): SerializedType 28 | { 29 | if (is_string($serializedJson)) { 30 | $serializedJson = (int) json_decode($serializedJson); 31 | } 32 | 33 | return new UnsignedInt8(Buffer::from(dechex($serializedJson))); 34 | } 35 | 36 | public function valueOf(): int|string 37 | { 38 | return $this->value->toInt(); 39 | } 40 | } -------------------------------------------------------------------------------- /src/Core/RippleKeyPairs/AbstractKeyPairService.php: -------------------------------------------------------------------------------- 1 | addressCodec = new AddressCodec(); 23 | } 24 | 25 | public function deriveAddress(Buffer|string $publicKey): string 26 | { 27 | //TODO: Check if this works properly 28 | return CoreUtilities::deriveAddress($publicKey); 29 | } 30 | 31 | public function getType(): string 32 | { 33 | return $this->type; 34 | } 35 | } -------------------------------------------------------------------------------- /src/Core/RippleKeyPairs/KeyPair.php: -------------------------------------------------------------------------------- 1 | publicKey = $publicKey; 20 | $this->privateKey = $privateKey; 21 | } 22 | 23 | /** 24 | * @return string 25 | */ 26 | public function getPublicKey(): string 27 | { 28 | return $this->publicKey; 29 | } 30 | 31 | /** 32 | * @param string $publicKey 33 | */ 34 | public function setPublicKey(string $publicKey): void 35 | { 36 | $this->publicKey = $publicKey; 37 | } 38 | 39 | /** 40 | * @return string 41 | */ 42 | public function getPrivateKey(): string 43 | { 44 | return $this->privateKey; 45 | } 46 | 47 | /** 48 | * @param string $privateKey 49 | */ 50 | public function setPrivateKey(string $privateKey): void 51 | { 52 | $this->privateKey = $privateKey; 53 | } 54 | 55 | public function toArray(): array 56 | { 57 | return [ 58 | 'publicKey' => $this->getPublicKey(), 59 | 'privateKey' => $this->getPrivateKey(), 60 | ]; 61 | } 62 | 63 | /** 64 | * @throws Exception Error 65 | */ 66 | public static function getKeyPairServiceByType(string $type = self::EDDSA): KeyPairServiceInterface 67 | { 68 | if ($type === self::EDDSA) { 69 | return Ed25519KeyPairService::getInstance(); 70 | } 71 | 72 | if ($type === self::EC) { 73 | return Secp256k1KeyPairService::getInstance(); 74 | } 75 | 76 | throw new Exception('No KeyPairService for type: ' . $type); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/Core/RippleKeyPairs/KeyPairServiceInterface.php: -------------------------------------------------------------------------------- 1 | [ 18 | 'issuer' => 'rMxCKbEDwqr76QuheSUMdEGf4B9xJ8m5De', 19 | 'currency' => '524C555344000000000000000000000000000000', 20 | ], 21 | 'testnet' => [ 22 | 'issuer' => 'rQhWct2fv4Vc4KRjRgMrxa8xPN9Zx9iLKV', 23 | 'currency' => 'USD', 24 | ], 25 | ]; 26 | 27 | public static function getRLUSD(string $network): array 28 | { 29 | if (isset(self::RLUSD[$network])) { 30 | return self::RLUSD[$network]; 31 | } 32 | 33 | throw new Exception('RLUSD not available for network: ' . $network); 34 | } 35 | 36 | public static function getRLUSDAmount(string $network, string $value): array 37 | { 38 | $rlusd = self::getRLUSD($network); 39 | 40 | return [ 41 | 'currency' => $rlusd['currency'], 42 | 'issuer' => $rlusd['issuer'], 43 | 'value' => $value, 44 | ]; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/Exceptions/ConnectionException.php: -------------------------------------------------------------------------------- 1 | name = self::class; 24 | $this->data = $data; 25 | 26 | parent::__construct($message); 27 | } 28 | 29 | /** 30 | * Converts the Error to a human-readable String form. 31 | * 32 | * @return string The String output of the Error. 33 | */ 34 | public function __toString(): string 35 | { 36 | $result = "[$this->message($this->message"; 37 | if (!empty($this->data)) { 38 | $result .= $this->data; 39 | } 40 | $result .= ")]"; 41 | 42 | return $result; 43 | } 44 | } -------------------------------------------------------------------------------- /src/Models/Account/AccountChannelsRequest.php: -------------------------------------------------------------------------------- 1 | result = $responsePayload['result']; 34 | 35 | if (isset($responsePayload['warnings'])) { 36 | $this->warnings = $responsePayload['warnings']; 37 | } 38 | } 39 | 40 | public function getResult(): array 41 | { 42 | return $this->result; 43 | } 44 | 45 | public function getStatus(): string 46 | { 47 | return $this->result['status']; 48 | } 49 | 50 | public function getWarnings(): array|null 51 | { 52 | return $this->warnings; 53 | } 54 | } -------------------------------------------------------------------------------- /src/Models/Clio/LedgerRequest.php: -------------------------------------------------------------------------------- 1 | $this->currency, 25 | 'issuer' => $this->issuer, 26 | 'value' => $this->value 27 | ]; 28 | } 29 | } -------------------------------------------------------------------------------- /src/Models/ErrorResponse.php: -------------------------------------------------------------------------------- 1 | id = $id; 35 | $this->statusCode = $statusCode; 36 | $this->error = $error; 37 | $this->errorCode = $errorCode; 38 | $this->errorMessage = $errorMessage; 39 | } 40 | 41 | public function getStatus(): string 42 | { 43 | return 'error'; 44 | } 45 | 46 | public function getStatusCode(): int 47 | { 48 | return $this->statusCode; 49 | } 50 | 51 | public function getError(): string 52 | { 53 | return $this->error; 54 | } 55 | } -------------------------------------------------------------------------------- /src/Models/Ledger/LedgerClosedRequest.php: -------------------------------------------------------------------------------- 1 | amm_account)) { 30 | if(is_null($this->asset) && is_null($this->asset2)) { 31 | throw new \InvalidArgumentException("amm_account or asset and asset2 must be set"); 32 | } 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /src/Models/PathOrderbook/AmmInfoResponse.php: -------------------------------------------------------------------------------- 1 | AccountId::class, 24 | 'DestinationTag' => UnsignedInt32::class 25 | ]; 26 | } -------------------------------------------------------------------------------- /src/Models/Transaction/TransactionTypes/AccountSet.php: -------------------------------------------------------------------------------- 1 | UnsignedInt32::class, 27 | 'Domain' => Blob::class, 28 | 'EmailHash' => Hash128::class, 29 | 'MessageKey' => Blob::class, 30 | 'NFTokenMinter' => Blob::class, 31 | 'SetFlag' => UnsignedInt32::class, 32 | 'TransferRate' => UnsignedInt32::class, 33 | 'TickSize' => UnsignedInt8::class, 34 | 'WalletLocator' => Hash256::class, 35 | 'WalletSize' => UnsignedInt32::class 36 | ]; 37 | } -------------------------------------------------------------------------------- /src/Models/Transaction/TransactionTypes/AmmBid.php: -------------------------------------------------------------------------------- 1 | Issue::class, 25 | 'Asset2' => Issue::class, 26 | 'BidMin' => Amount::class, 27 | 'BidMax' => Amount::class, 28 | 'AuthAccounts' => StArray::class 29 | ]; 30 | } -------------------------------------------------------------------------------- /src/Models/Transaction/TransactionTypes/AmmCreate.php: -------------------------------------------------------------------------------- 1 | Amount::class, 24 | 'Amount2' => Amount::class, 25 | 'TradingFee' => UnsignedInt16::class 26 | ]; 27 | } -------------------------------------------------------------------------------- /src/Models/Transaction/TransactionTypes/AmmDelete.php: -------------------------------------------------------------------------------- 1 | Amount::class, 23 | 'Amount2' => Amount::class 24 | ]; 25 | } -------------------------------------------------------------------------------- /src/Models/Transaction/TransactionTypes/AmmDeposit.php: -------------------------------------------------------------------------------- 1 | Issue::class, 24 | 'Asset2' => Issue::class, 25 | 'Amount' => Amount::class, 26 | 'Amount2' => Amount::class, 27 | 'EPrice' => Amount::class, 28 | 'LPTokenOut' => Amount::class 29 | ]; 30 | } -------------------------------------------------------------------------------- /src/Models/Transaction/TransactionTypes/AmmVote.php: -------------------------------------------------------------------------------- 1 | Issue::class, 24 | 'Asset2' => Issue::class, 25 | 'TradingFee' => UnsignedInt16::class 26 | ]; 27 | } -------------------------------------------------------------------------------- /src/Models/Transaction/TransactionTypes/AmmWithdraw.php: -------------------------------------------------------------------------------- 1 | Issue::class, 24 | 'Asset2' => Issue::class, 25 | 'Amount' => Amount::class, 26 | 'Amount2' => Amount::class, 27 | 'EPrice' => Amount::class, 28 | 'LPTokenOut' => Amount::class 29 | ]; 30 | } -------------------------------------------------------------------------------- /src/Models/Transaction/TransactionTypes/CheckCash.php: -------------------------------------------------------------------------------- 1 | Hash256::class, 24 | 'Amount' => Amount::class, 25 | 'DeliverMin' => Hash256::class, 26 | ]; 27 | } -------------------------------------------------------------------------------- /src/Models/Transaction/TransactionTypes/CheckChancel.php: -------------------------------------------------------------------------------- 1 | Hash256::class 23 | ]; 24 | } -------------------------------------------------------------------------------- /src/Models/Transaction/TransactionTypes/CheckCreate.php: -------------------------------------------------------------------------------- 1 | AccountId::class, 26 | 'SendMax' => Amount::class, 27 | 'DestinationTag' => UnsignedInt32::class, 28 | 'Expiration' => UnsignedInt32::class, 29 | 'InvoiceID' =>Hash256::class 30 | ]; 31 | } -------------------------------------------------------------------------------- /src/Models/Transaction/TransactionTypes/Clawback.php: -------------------------------------------------------------------------------- 1 | Amount::class 28 | ]; 29 | } -------------------------------------------------------------------------------- /src/Models/Transaction/TransactionTypes/DepositPreauth.php: -------------------------------------------------------------------------------- 1 | AccountId::class, 23 | 'Unauthorize' => AccountId::class 24 | ]; 25 | } -------------------------------------------------------------------------------- /src/Models/Transaction/TransactionTypes/EscrowCancel.php: -------------------------------------------------------------------------------- 1 | AccountId::class, 24 | 'OfferSequence' => UnsignedInt32::class 25 | ]; 26 | } -------------------------------------------------------------------------------- /src/Models/Transaction/TransactionTypes/EscrowCreate.php: -------------------------------------------------------------------------------- 1 | Amount::class, 26 | 'Destination' => AccountId::class, 27 | 'CancelAfter' => UnsignedInt32::class, 28 | 'FinishAfter' => UnsignedInt32::class, 29 | 'Condition' => Blob::class, 30 | 'DestinationTag' => UnsignedInt32::class, 31 | ]; 32 | } -------------------------------------------------------------------------------- /src/Models/Transaction/TransactionTypes/EscrowFinish.php: -------------------------------------------------------------------------------- 1 | AccountId::class, 25 | 'OfferSequence' => UnsignedInt32::class, 26 | 'Condition' => Blob::class, 27 | 'Fulfillment' => Blob::class, 28 | ]; 29 | } -------------------------------------------------------------------------------- /src/Models/Transaction/TransactionTypes/NFTokenAcceptOffer.php: -------------------------------------------------------------------------------- 1 | Hash256::class, 24 | 'NFTokenBuyOffer' => Hash256::class, 25 | 'NFTokenBrokerFee' => Amount::class 26 | ]; 27 | } -------------------------------------------------------------------------------- /src/Models/Transaction/TransactionTypes/NFTokenBurn.php: -------------------------------------------------------------------------------- 1 | Hash256::class, 24 | 'Owner' => AccountId::class 25 | ]; 26 | } -------------------------------------------------------------------------------- /src/Models/Transaction/TransactionTypes/NFTokenCancelOffer.php: -------------------------------------------------------------------------------- 1 | Vector256::class, 23 | ]; 24 | } -------------------------------------------------------------------------------- /src/Models/Transaction/TransactionTypes/NFTokenCreateOffer.php: -------------------------------------------------------------------------------- 1 | AccountId::class, 26 | 'NFTokenId' => Hash256::class, 27 | 'Amount' => Amount::class, 28 | 'Expiration' => UnsignedInt32::class, 29 | 'Destination' => AccountId::class 30 | ]; 31 | } -------------------------------------------------------------------------------- /src/Models/Transaction/TransactionTypes/NFTokenMint.php: -------------------------------------------------------------------------------- 1 | UnsignedInt32::class, 28 | 'Issuer' => AccountId::class, 29 | 'TransferFee' => UnsignedInt16::class, 30 | 'URI' => Blob::class, 31 | ]; 32 | } -------------------------------------------------------------------------------- /src/Models/Transaction/TransactionTypes/OfferCancel.php: -------------------------------------------------------------------------------- 1 | UnsignedInt32::class, 23 | ]; 24 | } -------------------------------------------------------------------------------- /src/Models/Transaction/TransactionTypes/OfferCreate.php: -------------------------------------------------------------------------------- 1 | UnsignedInt32::class, 24 | 'OfferSequence' => UnsignedInt32::class, 25 | 'TakerGets' => Amount::class, 26 | 'TakerPays' => Amount::class, 27 | ]; 28 | } -------------------------------------------------------------------------------- /src/Models/Transaction/TransactionTypes/Payment.php: -------------------------------------------------------------------------------- 1 | Amount::class, 27 | 'Destination' => AccountId::class, 28 | 'DestinationTag' => UnsignedInt32::class, 29 | 'InvoiceID' => Hash256::class, 30 | 'Paths' => PathSet::class, 31 | 'SendMax' => Amount::class, 32 | 'DeliverMin' => Amount::class, 33 | ]; 34 | } -------------------------------------------------------------------------------- /src/Models/Transaction/TransactionTypes/PaymentChannelClaim.php: -------------------------------------------------------------------------------- 1 | Hash256::class, 28 | 'Balance' => Amount::class, 29 | 'Amount' => Amount::class, 30 | 'Signature' => Blob::class, 31 | 'PublicKey' => Blob::class, 32 | ]; 33 | } -------------------------------------------------------------------------------- /src/Models/Transaction/TransactionTypes/PaymentChannelCreate.php: -------------------------------------------------------------------------------- 1 | Amount::class, 26 | 'Destination' => AccountId::class, 27 | 'SettleDelay' => UnsignedInt32::class, 28 | 'PublicKey' => Blob::class, 29 | 'ChancelAfter' => UnsignedInt32::class, 30 | 'DestinationTag' => UnsignedInt32::class, 31 | ]; 32 | } -------------------------------------------------------------------------------- /src/Models/Transaction/TransactionTypes/PaymentChannelFund.php: -------------------------------------------------------------------------------- 1 | Hash256::class, 25 | 'Amount' => Amount::class, 26 | 'Expiration' => UnsignedInt32::class, 27 | ]; 28 | } -------------------------------------------------------------------------------- /src/Models/Transaction/TransactionTypes/SetRegularKey.php: -------------------------------------------------------------------------------- 1 | AccountId::class, 23 | ]; 24 | } -------------------------------------------------------------------------------- /src/Models/Transaction/TransactionTypes/SignerListSet.php: -------------------------------------------------------------------------------- 1 | UnsignedInt32::class, 24 | 'SignerEntries' => StArray::class, 25 | ]; 26 | } -------------------------------------------------------------------------------- /src/Models/Transaction/TransactionTypes/TicketCreate.php: -------------------------------------------------------------------------------- 1 | UnsignedInt32::class 24 | ]; 25 | } -------------------------------------------------------------------------------- /src/Models/Transaction/TransactionTypes/TrustSet.php: -------------------------------------------------------------------------------- 1 | Amount::class, 24 | 'QualityIn' => UnsignedInt32::class, 25 | 'QualityOut' => UnsignedInt32::class, 26 | ]; 27 | } -------------------------------------------------------------------------------- /src/Models/Transaction/TxHistoryRequest.php: -------------------------------------------------------------------------------- 1 | body = json_decode($serializedJson, true); 34 | } 35 | 36 | public function getBody(): array 37 | { 38 | return $this->body; 39 | } 40 | } -------------------------------------------------------------------------------- /src/Models/Utility/JsonResponse.php: -------------------------------------------------------------------------------- 1 | getFeeCushion(); 29 | 30 | $serverInfoRequest = new ServerInfoRequest(); 31 | 32 | $serverInfoResponse = $client->request($serverInfoRequest)->wait(); 33 | 34 | $serverInfo = $serverInfoResponse->getResult()['info']; 35 | 36 | $baseFee = $serverInfo['validated_ledger']['base_fee_xrp'] ?? null; 37 | 38 | if(is_null($baseFee)) { 39 | throw new Exception('getFeeXrp: Could not get base_fee_xrp from server_info'); 40 | } 41 | 42 | $baseFeeXrp = BigDecimal::of($baseFee); 43 | if(is_null($serverInfo['load_factor'])) { 44 | $serverInfo['load_factor'] = 1; 45 | } 46 | 47 | $fee = $baseFeeXrp->multipliedBy($serverInfo['load_factor'])->multipliedBy($feeCushion); 48 | 49 | $fee = BigDecimal::min($fee, $client->getMaxFeeXrp()); 50 | 51 | //Round fee to 6 decimal places 52 | return $fee->toScale(6, RoundingMode::UP); 53 | } 54 | } -------------------------------------------------------------------------------- /src/Sugar/getTransactions.php: -------------------------------------------------------------------------------- 1 | getBody()); 27 | $response = $client->rawSyncRequest('POST', '', $body); 28 | 29 | $content = $response->getBody()->getContents(); 30 | $json = json_decode($content, true); 31 | 32 | return dropsToXrp($json['result']['account_data']['Balance']); 33 | } 34 | } 35 | 36 | if (! function_exists('Hardcastle\XRPL_PHP\Sugar\getBalances')) { 37 | 38 | function getBalances( 39 | JsonRpcClient $client, 40 | string $address, 41 | ?string $ledgerHash = null, 42 | ?string $ledgerIndex = null, 43 | ?string $peer = null, 44 | ?int $limit = null 45 | ): array 46 | { 47 | //TODO: Complete this function! 48 | 49 | $balances = []; 50 | 51 | $xrp = ''; 52 | if(!$peer) { 53 | $xrp = getXrpBalance($client, $address, $ledgerHash, $ledgerIndex); 54 | } 55 | 56 | $linesRequest = new AccountLinesRequest( 57 | $address, 58 | $ledgerHash, 59 | $ledgerIndex, 60 | $peer, 61 | $limit 62 | ); 63 | 64 | 65 | return array_slice($balances, 0, $limit); 66 | } 67 | } -------------------------------------------------------------------------------- /src/Utils/Utilities.php: -------------------------------------------------------------------------------- 1 | set(12, $isoBytes); 30 | } 31 | 32 | return $bytes->toString(); 33 | } 34 | 35 | public static function isIssuedCurrency(mixed $input): bool 36 | { 37 | return ( 38 | is_array($input) && 39 | count($input) === self::ISSUED_CURRENCY_SIZE && 40 | isset($input['currency']) && is_string($input['currency']) && 41 | isset($input['issuer']) && is_string($input['issuer']) && 42 | isset($input['value']) && is_string($input['value']) 43 | ); 44 | } 45 | 46 | /** 47 | * Converts a string to its hex equivalent. Useful for Memos. 48 | * 49 | * @param string $string 50 | * @return string 51 | */ 52 | public static function convertStringToHex(string $string): string 53 | { 54 | return Buffer::from($string, 'utf-8')->toString(); 55 | } 56 | 57 | /** 58 | * Converts hex to its string equivalent. Useful to read the Domain field and some Memos. 59 | * 60 | * @param string $hex 61 | * @return string 62 | * @throws \Exception 63 | */ 64 | public static function convertHexToString(string $hex): string 65 | { 66 | return Buffer::from($hex, 'hex')->toUtf8(); 67 | } 68 | } -------------------------------------------------------------------------------- /tests/Core/RippleAddressCodec/BaseXTest.php: -------------------------------------------------------------------------------- 1 | base58Codec = new BaseX(Utils::XRPL_ALPHABET); 25 | } 26 | 27 | public function testEncodeDecodeString(): void 28 | { 29 | $decoded = array_values(unpack('C*', "Hello World")); 30 | $encoded = "JxErpTiA7PhnBMd"; 31 | 32 | $this->assertEquals( 33 | $encoded, 34 | $this->base58Codec->encode(Buffer::from($decoded)) 35 | ); 36 | } 37 | } -------------------------------------------------------------------------------- /tests/Core/RippleBinaryCodec/BinaryParserTest.php: -------------------------------------------------------------------------------- 1 | fixtures = json_decode($raw, true); 24 | } 25 | 26 | //https://github.com/XRPLF/xrpl.js/blob/main/packages/ripple-binary-codec/test/binary-parser.test.js 27 | public function testLowLevelApi(): void 28 | { 29 | $parser = new BinaryParser($this->fixtures['binary']); 30 | 31 | $this->assertEquals( 32 | "TransactionType", //TODO: enums? 33 | $parser->readField()->getName() 34 | ); 35 | } 36 | 37 | //https://github.com/XRPLF/xrpl4j/blob/main/xrpl4j-binary-codec/src/test/java/org/xrpl/xrpl4j/codec/binary/XrplBinaryCodecTest.java 38 | } -------------------------------------------------------------------------------- /tests/Core/RippleBinaryCodec/Types/AccountIdTest.php: -------------------------------------------------------------------------------- 1 | assertEquals( 24 | $this->json, 25 | AccountId::fromHex($this->hex)->toJson() 26 | ); 27 | } 28 | 29 | public function testEncode(): void 30 | { 31 | $this->assertEquals( 32 | $this->hex, 33 | AccountId::fromJson($this->json)->toHex() 34 | ); 35 | } 36 | } -------------------------------------------------------------------------------- /tests/Core/RippleBinaryCodec/Types/BlobTest.php: -------------------------------------------------------------------------------- 1 | assertEquals($this->getBytes($width), Blob::fromHex($this->getBytes($width))->toString()); 21 | 22 | $width = 16; 23 | $this->assertEquals($this->getBytes($width), Blob::fromHex($this->getBytes($width))->toString()); 24 | 25 | $width = 32; 26 | $this->assertEquals($this->getBytes($width), Blob::fromHex($this->getBytes($width))->toString()); 27 | 28 | $width = 64; 29 | $this->assertEquals($this->getBytes($width), Blob::fromHex($this->getBytes($width))->toString()); 30 | 31 | $width = 128; 32 | $this->assertEquals($this->getBytes($width), Blob::fromHex($this->getBytes($width))->toString()); 33 | } 34 | 35 | public function testEncode(): void 36 | { 37 | $this->assertEquals($this->getBytes(16), Blob::fromJson($this->getBytes(16))->toHex()); 38 | } 39 | 40 | private function getBytes(int $size): string 41 | { 42 | return str_repeat("0F", $size); 43 | } 44 | } -------------------------------------------------------------------------------- /tests/Core/RippleBinaryCodec/Types/HashTest.php: -------------------------------------------------------------------------------- 1 | assertEquals( 22 | $this->getBytes(16), 23 | Hash128::fromHex($this->getBytes(16))->toHex() 24 | ); 25 | 26 | $this->assertEquals( 27 | $this->getBytes(20), 28 | Hash160::fromHex($this->getBytes(20))->toHex() 29 | ); 30 | 31 | $this->assertEquals( 32 | $this->getBytes(32), 33 | Hash256::fromHex($this->getBytes(32))->toHex() 34 | ); 35 | } 36 | 37 | public function testEncode(): void 38 | { 39 | $this->assertEquals( 40 | $this->getBytes(16), 41 | Hash128::fromJson($this->getBytes(16))->toHex() 42 | ); 43 | 44 | $this->assertEquals( 45 | $this->getBytes(20), 46 | Hash160::fromJson($this->getBytes(20))->toHex() 47 | ); 48 | 49 | $this->assertEquals( 50 | $this->getBytes(32), 51 | Hash256::fromJson($this->getBytes(32))->toHex() 52 | ); 53 | } 54 | 55 | private function getBytes(int $size): string 56 | { 57 | return str_repeat("0F", $size); 58 | } 59 | } -------------------------------------------------------------------------------- /tests/Core/RippleBinaryCodec/Types/IssueTest.php: -------------------------------------------------------------------------------- 1 | getZeroBytes(20); 13 | $json = "{\"currency\":\"XRP\"}"; 14 | 15 | $this->assertEquals( 16 | json_decode($json, true), 17 | Issue::fromHex($hex)->toJson() 18 | ); 19 | 20 | $hex = "0000000000000000000000005453540000000000F2F97C4301C80D60F86653A319AA7F302C70B83B"; 21 | $json = "{\"currency\":\"TST\",\"issuer\":\"rP9jPyP5kyvFRb6ZiRghAGw5u8SGAmU4bd\"}"; 22 | 23 | $this->assertEquals( 24 | json_decode($json, true), 25 | Issue::fromHex($hex)->toJson() 26 | ); 27 | } 28 | 29 | public function testEncode(): void 30 | { 31 | 32 | $hex = $this->getZeroBytes(20); 33 | $json = "{\"currency\":\"XRP\"}"; 34 | 35 | $this->assertEquals( 36 | $hex, 37 | Issue::fromJson($json)->toHex() 38 | ); 39 | 40 | $hex = "0000000000000000000000005453540000000000F2F97C4301C80D60F86653A319AA7F302C70B83B"; 41 | $json = "{\"currency\":\"TST\",\"issuer\":\"rP9jPyP5kyvFRb6ZiRghAGw5u8SGAmU4bd\"}"; 42 | 43 | $this->assertEquals( 44 | $hex, 45 | Issue::fromJson($json)->toHex() 46 | ); 47 | } 48 | 49 | private function getZeroBytes(int $size): string 50 | { 51 | return str_repeat("00", $size); 52 | } 53 | } -------------------------------------------------------------------------------- /tests/Core/RippleBinaryCodec/Types/PathStepTest.php: -------------------------------------------------------------------------------- 1 | "r9hEDb4xBGRfBCcX3E4FirDWQBAYtpxC8K", 19 | "currency" => "BTC", 20 | "issuer" => "r9hEDb4xBGRfBCcX3E4FirDWQBAYtpxC8K", 21 | ]; 22 | 23 | private string $hex = "31585E1F3BD02A15D6185F8BB9B57CC60DEDDB37C10000000000000000000000004254430000000000585E1F3BD02A15D6185F8BB9B57CC60DEDDB37C1"; 24 | 25 | public function testDecode(): void 26 | { 27 | $this->assertEquals( 28 | $this->json, 29 | PathStep::fromHex($this->hex)->toJson() 30 | ); 31 | } 32 | 33 | public function testEncode(): void 34 | { 35 | $serializedJson = json_encode($this->json); 36 | $this->assertEquals( 37 | $this->hex, 38 | PathStep::fromJson($serializedJson)->toHex() 39 | ); 40 | } 41 | } -------------------------------------------------------------------------------- /tests/Core/RippleBinaryCodec/Types/PathTest.php: -------------------------------------------------------------------------------- 1 | json = [ 19 | [ 20 | "account" => "r9hEDb4xBGRfBCcX3E4FirDWQBAYtpxC8K", 21 | "currency" => "BTC", 22 | "issuer" => "r9hEDb4xBGRfBCcX3E4FirDWQBAYtpxC8K", 23 | ], 24 | [ 25 | "account" => "r3AWbdp2jQLXLywJypdoNwVSvr81xs3uhn", 26 | "currency" => "BTC", 27 | "issuer" => "r3AWbdp2jQLXLywJypdoNwVSvr81xs3uhn", 28 | ], 29 | [ 30 | "currency" => "XRP" 31 | ], 32 | [ 33 | "currency" => "USD", 34 | "issuer" => "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B", 35 | ], 36 | ]; 37 | 38 | $this->hex = "31585E1F3BD02A15D6185F8BB9B57CC60DEDDB37C10000000000000000000000004254430000000000585E1F3BD02A15D6185F8BB9B57CC60DEDDB37C13157180C769B66D942EE69E6DCC940CA48D82337AD000000000000000000000000425443000000000057180C769B66D942EE69E6DCC940CA48D82337AD1000000000000000000000000000000000000000003000000000000000000000000055534400000000000A20B3C85F482532A9578DBB3950B85CA06594D1"; 39 | } 40 | 41 | 42 | public function testDecode(): void 43 | { 44 | $this->assertEquals( 45 | $this->json, 46 | Path::fromHex($this->hex)->toJson() 47 | ); 48 | } 49 | 50 | public function testEncode(): void 51 | { 52 | $serializedJson = json_encode($this->json); 53 | $this->assertEquals( 54 | $this->hex, 55 | Path::fromJson($serializedJson)->toHex() 56 | ); 57 | } 58 | } -------------------------------------------------------------------------------- /tests/Core/RippleBinaryCodec/Types/StArrayTest.php: -------------------------------------------------------------------------------- 1 | fixtures = json_decode($raw, true); 25 | 26 | $this->json = [ 27 | ["Memo" => $this->fixtures['Memo']], 28 | ["Memo" => $this->fixtures['Memo']] 29 | ]; 30 | $this->hex = $this->fixtures['MemoHex'] . $this->fixtures['MemoHex'] . StArray::ARRAY_END_MARKER_HEX; 31 | 32 | parent::setUp(); 33 | } 34 | 35 | public function testDecodeStArray(): void 36 | { 37 | $this->assertEquals( 38 | $this->json, 39 | StArray::fromHex($this->hex)->toJson() 40 | ); 41 | 42 | } 43 | 44 | public function testEncodeStArray(): void 45 | { 46 | $this->assertEquals( 47 | $this->hex, 48 | StArray::fromJson(json_encode($this->json))->toString() 49 | ); 50 | } 51 | } -------------------------------------------------------------------------------- /tests/Core/RippleBinaryCodec/Types/StObjectTest.php: -------------------------------------------------------------------------------- 1 | fixtures = json_decode($raw, true); 28 | 29 | $this->json = ["Memo" => $this->fixtures['Memo']]; 30 | $this->hex = $this->fixtures['MemoHex']; 31 | 32 | parent::setUp(); 33 | } 34 | 35 | public function testDecodeStObject(): void 36 | { 37 | $this->assertEquals( 38 | $this->json, 39 | StObject::fromHex($this->hex)->toJson() 40 | ); 41 | 42 | } 43 | 44 | public function testEncodeStObject(): void 45 | { 46 | $this->assertEquals( 47 | $this->hex, 48 | StObject::fromJson(json_encode($this->json))->toString() 49 | ); 50 | } 51 | } -------------------------------------------------------------------------------- /tests/Core/RippleBinaryCodec/Types/Vector256Test.php: -------------------------------------------------------------------------------- 1 | json = json_encode([self::VALUE1, self::VALUE2]); 31 | $this->hex = self::VALUE1 . self::VALUE2; 32 | } 33 | 34 | public function testDecode(): void 35 | { 36 | $this->assertEquals( 37 | $this->json, 38 | Vector256::fromHex($this->hex)->toJson() 39 | ); 40 | } 41 | 42 | public function testEncode(): void 43 | { 44 | $this->assertEquals( 45 | $this->hex, 46 | Vector256::fromJson($this->json)->toHex() 47 | ); 48 | } 49 | } -------------------------------------------------------------------------------- /tests/Core/RippleBinaryCodec/Types/XchainBridgeTest.php: -------------------------------------------------------------------------------- 1 | "rGzx83BVoqTYbGn7tiVAnFw7cbxjin13jL", 14 | "LockingChainIssue" => ["currency" => "XRP"], 15 | "IssuingChainDoor" => "r3kmLJN5D28dHuH8vZNUZpMC43pEHpaocV", 16 | "IssuingChainIssue" => ["currency" => "XRP"] 17 | ]; 18 | 19 | public function testDecode(): void 20 | { 21 | $this->assertEquals( 22 | $this->json, 23 | XchainBridge::fromHex($this->hex)->toJson() 24 | ); 25 | } 26 | 27 | public function testEncode(): void 28 | { 29 | $this->assertEquals( 30 | $this->hex, 31 | XchainBridge::fromJson(json_encode($this->json))->toHex() 32 | ); 33 | } 34 | } -------------------------------------------------------------------------------- /tests/Core/RippleBinaryCodec/Types/fixtures.json: -------------------------------------------------------------------------------- 1 | { 2 | "Memo": { 3 | "MemoType": "687474703A2F2F6578616D706C652E636F6D2F6D656D6F2F67656E65726963", 4 | "MemoData": "72656E74" 5 | }, 6 | "MemoHex": "EA7C1F687474703A2F2F6578616D706C652E636F6D2F6D656D6F2F67656E657269637D0472656E74E1" 7 | 8 | } -------------------------------------------------------------------------------- /tests/Core/RippleBinaryCodec/fixtures.json: -------------------------------------------------------------------------------- 1 | { 2 | "json": { 3 | "Account": "raD5qJMAShLeHZXf9wjUmo6vRK4arj9cF3", 4 | "Fee": "10", 5 | "Flags": 0, 6 | "Sequence": 103929, 7 | "SigningPubKey": "028472865AF4CB32AA285834B57576B7290AA8C31B459047DB27E16F418D6A7166", 8 | "TakerGets": { 9 | "currency": "ILS", 10 | "issuer": "rNPRNzBB92BVpAhhZr4iXDTveCgV5Pofm9", 11 | "value": "1694.768" 12 | }, 13 | "TakerPays": "98957503520", 14 | "TransactionType": "OfferCreate", 15 | "TxnSignature": "304502202ABE08D5E78D1E74A4C18F2714F64E87B8BD57444AFA5733109EB3C077077520022100DB335EE97386E4C0591CAC024D50E9230D8F171EEB901B5E5E4BD6D1E0AEF98C" 16 | }, 17 | "binary": "120007220000000024000195F964400000170A53AC2065D5460561EC9DE000000000000000000000000000494C53000000000092D705968936C419CE614BF264B5EEB1CEA47FF468400000000000000A7321028472865AF4CB32AA285834B57576B7290AA8C31B459047DB27E16F418D6A71667447304502202ABE08D5E78D1E74A4C18F2714F64E87B8BD57444AFA5733109EB3C077077520022100DB335EE97386E4C0591CAC024D50E9230D8F171EEB901B5E5E4BD6D1E0AEF98C811439408A69F0895E62149CFCC006FB89FA7D1E6E5D" 18 | } -------------------------------------------------------------------------------- /tests/Core/RippleKeyPairs/fixtures.json: -------------------------------------------------------------------------------- 1 | { 2 | "secp256k1": { 3 | "seed": "sp5fghtJtpUorTwvof1NpDXAzNwf5", 4 | "keypair": { 5 | "privateKey": "00D78B9735C3F26501C7337B8A5727FD53A6EFDBC6AA55984F098488561F985E23", 6 | "publicKey": "030D58EB48B4420B1F7B9DF55087E0E29FEF0E8468F9A6825B01CA2C361042D435" 7 | }, 8 | "validatorKeypair": { 9 | "privateKey": "001A6B48BF0DE7C7E425B61E0444E3921182B6529867685257CEDC3E7EF13F0F18", 10 | "publicKey": "03B462771E99AAE9C7912AF47D6120C0B0DA972A4043A17F26320A52056DA46EA8" 11 | }, 12 | "address": "rU6K7V3Po4snVhBBaU29sesqs2qTQJWDw1", 13 | "message": "test message", 14 | "signature": "30440220583A91C95E54E6A651C47BEC22744E0B101E2C4060E7B08F6341657DAD9BC3EE02207D1489C7395DB0188D3A56A977ECBA54B36FA9371B40319655B1B4429E33EF2D" 15 | }, 16 | "ed25519": { 17 | "seed": "sEdSKaCy2JT7JaM7v95H9SxkhP9wS2r", 18 | "keypair": { 19 | "privateKey": "EDB4C4E046826BD26190D09715FC31F4E6A728204EADD112905B08B14B7F15C4F3", 20 | "publicKey": "ED01FA53FA5A7E77798F882ECE20B1ABC00BB358A9E55A202D0D0676BD0CE37A63" 21 | }, 22 | "validatorKeypair": { 23 | "privateKey": "EDB4C4E046826BD26190D09715FC31F4E6A728204EADD112905B08B14B7F15C4F3", 24 | "publicKey": "ED01FA53FA5A7E77798F882ECE20B1ABC00BB358A9E55A202D0D0676BD0CE37A63" 25 | }, 26 | "address": "rLUEXYuLiQptky37CqLcm9USQpPiz5rkpD", 27 | "message": "test message", 28 | "signature": "CB199E1BFD4E3DAA105E4832EEDFA36413E1F44205E4EFB9E27E826044C21E3E2E848BBC8195E8959BADF887599B7310AD1B7047EF11B682E0D068F73749750E" 29 | } 30 | } -------------------------------------------------------------------------------- /tests/Core/UtilitiesTest.php: -------------------------------------------------------------------------------- 1 | assertInstanceOf(CoreUtilities::class, $firstCall); 16 | $this->assertSame($firstCall, $secondCall); 17 | } 18 | 19 | public function testEncodeCustomCurrency(): void 20 | { 21 | $customCurrency = "SOLO"; 22 | $hash = CoreUtilities::encodeCustomCurrency($customCurrency); 23 | $this->assertEquals('534F4C4F00000000000000000000000000000000', $hash); 24 | } 25 | 26 | public function testDecodecustomCurrency(): void 27 | { 28 | $hash = '534F4C4F00000000000000000000000000000000'; 29 | $currency = CoreUtilities::decodeCustomCurrency($hash); 30 | $this->assertEquals('SOLO', $currency); 31 | } 32 | 33 | } -------------------------------------------------------------------------------- /tests/Fixtures/Requests/getOrderbook.json: -------------------------------------------------------------------------------- 1 | { 2 | "takerPays": { 3 | "currency": "USD", 4 | "issuer": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B" 5 | }, 6 | "takerGets": { 7 | "currency": "BTC", 8 | "issuer": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /tests/Fixtures/Requests/getOrderbookWithXrp.json: -------------------------------------------------------------------------------- 1 | { 2 | "takerPays": { 3 | "currency": "USD", 4 | "issuer": "rp8rJYTpodf8qbSCHVTNacf8nSW8mRakFw" 5 | }, 6 | "takerGets": { 7 | "currency": "XRP" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /tests/Fixtures/Requests/hashLedger.json: -------------------------------------------------------------------------------- 1 | { 2 | "account_hash": "D9ABF622DA26EEEE48203085D4BC23B0F77DC6F8724AC33D975DA3CA492D2E44", 3 | "close_time": 492656470, 4 | "parent_close_time": 492656460, 5 | "close_flags": 0, 6 | "ledger_index": "15202439", 7 | "close_time_human": "2015-Aug-12 01:01:10.000000000 UTC", 8 | "close_time_resolution": 10, 9 | "closed": true, 10 | "hash": "F4D865D83EB88C1A1911B9E90641919A1314F36E1B099F8E95FE3B7C77BE3349", 11 | "ledger_hash": "F4D865D83EB88C1A1911B9E90641919A1314F36E1B099F8E95FE3B7C77BE3349", 12 | "parent_hash": "12724A65B030C15A1573AA28B1BBB5DF3DA4589AA3623675A31CAE69B23B1C4E", 13 | "total_coins": "99998831688050493", 14 | "transaction_hash": "325EACC5271322539EEEC2D6A5292471EF1B3E72AE7180533EFC3B8F0AD435C8" 15 | } 16 | -------------------------------------------------------------------------------- /tests/Fixtures/Requests/sign.json: -------------------------------------------------------------------------------- 1 | { 2 | "TransactionType":"AccountSet", 3 | "Flags":2147483648, 4 | "Sequence":23, 5 | "LastLedgerSequence":8820051, 6 | "Fee":"12", 7 | "SigningPubKey":"02A8A44DB3D4C73EEEE11DFE54D2029103B776AA8A8D293A91D645977C9DF5F544", 8 | "Domain":"6578616D706C652E636F6D", 9 | "Account":"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59" 10 | } 11 | -------------------------------------------------------------------------------- /tests/Fixtures/Requests/signAs.json: -------------------------------------------------------------------------------- 1 | { 2 | "Account": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA", 3 | "Amount": "1000000000", 4 | "Destination": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", 5 | "Fee": "50", 6 | "Sequence": 2, 7 | "TransactionType": "Payment" 8 | } 9 | -------------------------------------------------------------------------------- /tests/Fixtures/Requests/signEscrow.json: -------------------------------------------------------------------------------- 1 | { 2 | "TransactionType":"EscrowFinish", 3 | "Account":"rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", 4 | "Owner":"rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", 5 | "OfferSequence":2, 6 | "Condition":"712C36933822AD3A3D136C5DF97AA863B69F9CE88B2D6CE6BDD11BFDE290C19D", 7 | "Fulfillment":"74686973206D757374206861766520333220636861726163746572732E2E2E2E", 8 | "Flags":2147483648, 9 | "LastLedgerSequence":102, 10 | "Fee":"12", 11 | "Sequence":1 12 | } 13 | -------------------------------------------------------------------------------- /tests/Fixtures/Requests/signPaymentChannelClaim.json: -------------------------------------------------------------------------------- 1 | { 2 | "channel": "3E18C05AD40319B809520F1A136370C4075321B285217323396D6FD9EE1E9037", 3 | "amount": ".00001" 4 | } 5 | -------------------------------------------------------------------------------- /tests/Fixtures/Requests/signTicket.json: -------------------------------------------------------------------------------- 1 | { 2 | "TransactionType":"TicketCreate", 3 | "TicketCount":1, 4 | "Account":"r4SDqUD1ZcfoZrhnsZ94XNFKxYL4oHYJyA", 5 | "Sequence":0, 6 | "TicketSequence":23, 7 | "Fee":"10000" 8 | } 9 | -------------------------------------------------------------------------------- /tests/Fixtures/Responses/generateAddress.json: -------------------------------------------------------------------------------- 1 | { 2 | "xAddress": "XVLcsWWNiFdUEqoDmSwgxh1abfddG1LtbGFk7omPgYpbyE8", 3 | "classicAddress": "rGCkuB7PBr5tNy68tPEABEtcdno4hE6Y7f", 4 | "secret": "sp6JS7f14BuwFY8Mw6bTtLKWauoUs" 5 | } 6 | -------------------------------------------------------------------------------- /tests/Fixtures/Responses/generateXAddress.json: -------------------------------------------------------------------------------- 1 | { 2 | "xAddress": "XVLcsWWNiFdUEqoDmSwgxh1abfddG1LtbGFk7omPgYpbyE8", 3 | "secret": "sp6JS7f14BuwFY8Mw6bTtLKWauoUs" 4 | } 5 | -------------------------------------------------------------------------------- /tests/Fixtures/Responses/getOrderbookWithXrp.json: -------------------------------------------------------------------------------- 1 | { 2 | "buy": [ 3 | { 4 | "Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", 5 | "BookDirectory": "A118405CF7C2C89AB0CC084417187B86870DC14325C861A0470E1AEE5CBE20D9", 6 | "BookNode": "0000000000000000", 7 | "Flags": 0, 8 | "LedgerEntryType": "Offer", 9 | "OwnerNode": "0000000000000000", 10 | "PreviousTxnID": "9DD36CC7338FEB9E501A33EAAA4C00DBE4ED3A692704C62DDBD1848EE1F6E762", 11 | "PreviousTxnLgrSeq": 11, 12 | "Sequence": 5, 13 | "TakerGets": "254391353000000", 14 | "TakerPays": { 15 | "currency": "USD", 16 | "issuer": "rp8rJYTpodf8qbSCHVTNacf8nSW8mRakFw", 17 | "value": "10.1" 18 | }, 19 | "index": "BF656DABDD84E6128A45039F8D557C9477D4DA31F5B00868F2191F0A11FE3798", 20 | "owner_funds": "99999998959999928", 21 | "quality": "3970260734451929e-29" 22 | } 23 | ], 24 | "sell": [ 25 | { 26 | "Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", 27 | "BookDirectory": "A118405CF7C2C89AB0CC084417187B86870DC14325C861A0561BB6E89EFF509C", 28 | "BookNode": "0000000000000000", 29 | "Flags": 131072, 30 | "LedgerEntryType": "Offer", 31 | "OwnerNode": "0000000000000000", 32 | "PreviousTxnID": "CFB5786459E568DFC504E7319C515658DED657A7F4EFB5957B33E5E3BD9A1353", 33 | "PreviousTxnLgrSeq": 13, 34 | "Sequence": 6, 35 | "TakerGets": { 36 | "currency": "USD", 37 | "issuer": "rp8rJYTpodf8qbSCHVTNacf8nSW8mRakFw", 38 | "value": "10453252347.1" 39 | }, 40 | "TakerPays": "134000000", 41 | "index": "C72CDC1BA4DA529B062871F22C6D175A4D97D4F1160D0D7E646E60699278B5B5", 42 | "quality": "78.0093458738806" 43 | } 44 | ] 45 | } 46 | -------------------------------------------------------------------------------- /tests/Fixtures/Responses/getServerInfo.json: -------------------------------------------------------------------------------- 1 | { 2 | "build_version": "0.24.0-rc1", 3 | "complete_ledgers": "32570-6595042", 4 | "hostid": "ARTS", 5 | "io_latency_ms": 1, 6 | "last_close": { 7 | "converge_time_s": 2.007, 8 | "proposers": 4 9 | }, 10 | "load_factor": 1, 11 | "peers": 53, 12 | "pubkey_node": "n94wWvFUmaKGYrKUGgpv1DyYgDeXRGdACkNQaSe7zJiy5Znio7UC", 13 | "server_state": "full", 14 | "validated_ledger": { 15 | "age": 5, 16 | "base_fee_xrp": 0.00001, 17 | "hash": "4482DEE5362332F54A4036ED57EE1767C9F33CF7CE5A6670355C16CECE381D46", 18 | "reserve_base_xrp": 20, 19 | "reserve_inc_xrp": 5, 20 | "seq": 6595042 21 | }, 22 | "validation_quorum": 3 23 | } 24 | -------------------------------------------------------------------------------- /tests/Fixtures/Responses/sign.json: -------------------------------------------------------------------------------- 1 | { 2 | "signedTransaction": "12000322800000002400000017201B0086955368400000000000000C732102A8A44DB3D4C73EEEE11DFE54D2029103B776AA8A8D293A91D645977C9DF5F54474463044022025464FA5466B6E28EEAD2E2D289A7A36A11EB9B269D211F9C76AB8E8320694E002205D5F99CB56E5A996E5636A0E86D029977BEFA232B7FB64ABA8F6E29DC87A9E89770B6578616D706C652E636F6D81145E7B112523F68D2F5E879DB4EAC51C6698A69304", 3 | "id": "93F6C6CE73C092AA005103223F3A1F557F4C097A2943D96760F6490F04379917" 4 | } 5 | -------------------------------------------------------------------------------- /tests/Fixtures/Responses/signAs.json: -------------------------------------------------------------------------------- 1 | { 2 | "signedTransaction": "120000240000000261400000003B9ACA00684000000000000032730081142E244E6F20104E57C0C60BD823CB312BF10928C78314B5F762798A53D543A014CAF8B297CFF8F2F937E8F3E010732102A8A44DB3D4C73EEEE11DFE54D2029103B776AA8A8D293A91D645977C9DF5F54474473045022100B3F8205578C6A68D3BBD27650F5D2E983718D502C250C5147F07B7EDD8E8583E02207B892818BD58E328C2797F15694A505937861586D527849065B582523E390B128114B3263BD0A9BF9DFDBBBBD07F536355FF477BF0E9E1F1", 3 | "id": "D8CF5FC93CFE5E131A34599AFB7CE186A5B8D1B9F069E35F4634AD3B27837E35" 4 | } 5 | -------------------------------------------------------------------------------- /tests/Fixtures/Responses/signEscrow.json: -------------------------------------------------------------------------------- 1 | { 2 | "signedTransaction": "12000222800000002400000001201900000002201B0000006668400000000000000C732102A8A44DB3D4C73EEEE11DFE54D2029103B776AA8A8D293A91D645977C9DF5F5447446304402204652E8572AEED964451C603EB110AC9945A65E3C5C288D144BB02F259755F6E202205B64E27293248F0650A3F7A4FD66BC16A61F4883AC3ED8EE8A48EF569C06812070102074686973206D757374206861766520333220636861726163746572732E2E2E2E701120712C36933822AD3A3D136C5DF97AA863B69F9CE88B2D6CE6BDD11BFDE290C19D8114B5F762798A53D543A014CAF8B297CFF8F2F937E88214B5F762798A53D543A014CAF8B297CFF8F2F937E8", 3 | "id": "645B7676DF057E4F5E83F970A18B3751B6813807F1030A8D2F482D02DC885106" 4 | } 5 | -------------------------------------------------------------------------------- /tests/Fixtures/Responses/signPaymentChannelClaim.json: -------------------------------------------------------------------------------- 1 | "3045022100B5C54654221F154347679B97AE7791CBEF5E6772A3F894F9C781B8F1B400F89F022021E466D29DC5AEB5DFAFC76E8A88D2E388EBD25A84143B6AC3B647F479CB89B7" 2 | -------------------------------------------------------------------------------- /tests/Fixtures/Responses/signTicket.json: -------------------------------------------------------------------------------- 1 | { 2 | "signedTransaction": "12000A2400000000202800000001202900000017684000000000002710732102A8A44DB3D4C73EEEE11DFE54D2029103B776AA8A8D293A91D645977C9DF5F54474473045022100896CFE083767C88B9539DE2F28894429BC2760865161792D576C090BB93E1EAA02203015D30BC59245C8CFB8A9D78386B91B251DCB946A4C0FAB12A5FA41C202FF3A8114EB1FC04FDA0248FB6DE5BA4235425773D61DF0F3", 3 | "id": "0AC60B1E1F063904D9D9D0E9D03F2E9C8D41BC6FC872D5B8BF87E15BBF9669BB" 4 | } 5 | -------------------------------------------------------------------------------- /tests/Integration/BasicIntegrationTest.php: -------------------------------------------------------------------------------- 1 | client = new JsonRpcClient(self::TESTNET_URL); 28 | } 29 | 30 | public function testPing(): void 31 | { 32 | $pingRequest = new PingRequest(); 33 | 34 | $body = json_encode($pingRequest->getBody()); 35 | 36 | $response = $this->client->rawSyncRequest('POST', '', $body); 37 | $content = (string) $response->getBody(); 38 | 39 | $this->assertEquals( 40 | ["result" => ["status" => "success"]], 41 | json_decode($content, true) 42 | ); 43 | } 44 | 45 | /* 46 | public function testTx(): void 47 | { 48 | //From: https://testnet.xrpl.org/transactions/06DF196953B57AD17A9DF16AE22D4C466F78AAC07369B5E0F64780CA903BAC8D 49 | $txRequest = new TxRequest(transaction: "06DF196953B57AD17A9DF16AE22D4C466F78AAC07369B5E0F64780CA903BAC8D"); 50 | 51 | $body = json_encode($txRequest->getBody()); 52 | 53 | $response = $this->client->rawSyncRequest('POST', '', $body); 54 | $content = (string) $response->getBody(); 55 | $status = json_decode($content, true)['result']['status']; 56 | 57 | $this->assertEquals( 58 | "success", 59 | $status 60 | ); 61 | } 62 | */ 63 | } -------------------------------------------------------------------------------- /tests/Integration/FundWalletTest.php: -------------------------------------------------------------------------------- 1 | client = new JsonRpcClient(self::TESTNET_URL); 19 | } 20 | 21 | public function testGenerateTestnetWallet(): void 22 | { 23 | $pingRequest = new PingRequest(); 24 | 25 | $body = json_encode($pingRequest->getBody()); 26 | 27 | $response = $this->client->rawSyncRequest('POST', '', $body); 28 | $content = (string) $response->getBody(); 29 | 30 | $this->assertEquals( 31 | ["result" => ["status" => "success"]], 32 | json_decode($content, true) 33 | ); 34 | } 35 | 36 | /* 37 | public function testTx(): void 38 | { 39 | //From: https://testnet.xrpl.org/transactions/06DF196953B57AD17A9DF16AE22D4C466F78AAC07369B5E0F64780CA903BAC8D 40 | $txRequest = new TxRequest(transaction: "06DF196953B57AD17A9DF16AE22D4C466F78AAC07369B5E0F64780CA903BAC8D"); 41 | 42 | $body = json_encode($txRequest->getBody()); 43 | 44 | $response = $this->client->rawSyncRequest('POST', '', $body); 45 | $content = (string) $response->getBody(); 46 | $status = json_decode($content, true)['result']['status']; 47 | 48 | $this->assertEquals( 49 | "success", 50 | $status 51 | ); 52 | } 53 | */ 54 | } -------------------------------------------------------------------------------- /tests/MockRippled/Fixtures/Requests/serverInfo.json: -------------------------------------------------------------------------------- 1 | { 2 | "method": "server_info", 3 | "params": [ 4 | { 5 | "api_version": 1 6 | } 7 | ] 8 | } -------------------------------------------------------------------------------- /tests/MockRippled/Fixtures/Responses/serverInfo.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": 0, 3 | "status": "success", 4 | "type": "response", 5 | "result": { 6 | "info": { 7 | "build_version": "0.24.0-rc1", 8 | "complete_ledgers": "32570-6595042", 9 | "hostid": "ARTS", 10 | "io_latency_ms": 1, 11 | "last_close": { 12 | "converge_time_s": 2.007, 13 | "proposers": 4 14 | }, 15 | "load_factor": 1, 16 | "peers": 53, 17 | "pubkey_node": "n94wWvFUmaKGYrKUGgpv1DyYgDeXRGdACkNQaSe7zJiy5Znio7UC", 18 | "server_state": "full", 19 | "validated_ledger": { 20 | "age": 5, 21 | "base_fee_xrp": 0.00001, 22 | "hash": "4482DEE5362332F54A4036ED57EE1767C9F33CF7CE5A6670355C16CECE381D46", 23 | "reserve_base_xrp": 20, 24 | "reserve_inc_xrp": 5, 25 | "seq": 6595042 26 | }, 27 | "validation_quorum": 3 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /tests/MockRippled/MockRippledResponse.php: -------------------------------------------------------------------------------- 1 | requestJson = $requestJson; 21 | 22 | if(is_array($responseJson)) { 23 | $responseJson = json_encode($responseJson); 24 | } 25 | 26 | parent::__construct($responseJson); 27 | } 28 | 29 | /** 30 | * @inheritdoc 31 | */ 32 | public function getRef(): string { 33 | $content = json_encode([ 34 | $this->requestJson, 35 | 200, 36 | [], 37 | ]); 38 | 39 | return md5($content); 40 | } 41 | } -------------------------------------------------------------------------------- /tests/MockRippled/MockRippledServer.php: -------------------------------------------------------------------------------- 1 | needsBcmathExtension(); 13 | } 14 | 15 | public function testBchexdec() 16 | { 17 | $this->assertEquals('18446744073709551615', bchexdec('FFFFFFFFFFFFFFFF')); 18 | $this->assertEquals('9223372036854775807', bchexdec('7FFFFFFFFFFFFFFF')); 19 | $this->assertEquals('9223372036854775808', bchexdec('8000000000000000')); 20 | $this->assertEquals('0', bchexdec('0')); 21 | } 22 | 23 | public function testBcdechex() 24 | { 25 | $this->assertEquals('FFFFFFFFFFFFFFFF', bcdechex('18446744073709551615')); 26 | $this->assertEquals('7FFFFFFFFFFFFFFF', bcdechex('9223372036854775807')); 27 | $this->assertEquals('8000000000000000', bcdechex('9223372036854775808')); 28 | $this->assertEquals('0', bcdechex('0')); 29 | } 30 | 31 | public function testHex2str(): void 32 | { 33 | $this->assertEquals('Hello World!', hex2str('48656c6c6f20576f726c6421')); 34 | } 35 | 36 | public function testStr2hex(): void 37 | { 38 | $this->assertEquals('48656c6c6f20576f726c6421', str2hex('Hello World!')); 39 | } 40 | 41 | private function needsBcmathExtension() 42 | { 43 | if (!extension_loaded('bcmath')) { 44 | $this->markTestSkipped('The bcmath extension is not available.'); 45 | } 46 | } 47 | } -------------------------------------------------------------------------------- /tests/Sugar/BalancesTest.php: -------------------------------------------------------------------------------- 1 | start(); 25 | } 26 | 27 | public function setUp(): void 28 | { 29 | $mockRippledUrl = self::$server->getServerRoot(); 30 | $this->client = new JsonRpcClient($mockRippledUrl); 31 | } 32 | 33 | public function testGetXrpBalance(): void 34 | { 35 | //TODO: Implement test 36 | $this->assertEquals(true, true); 37 | } 38 | 39 | public function testGetBalances(): void 40 | { 41 | //TODO: Implement test 42 | $this->assertEquals(true, true); 43 | } 44 | } -------------------------------------------------------------------------------- /tests/Utils/UtilitiesTest.php: -------------------------------------------------------------------------------- 1 | assertEquals($res, Utilities::convertStringToHex($str)); 28 | 29 | $str = 'ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf4dfuylqabf3oclgtqy55fbzdi'; 30 | $res = '697066733A2F2F62616679626569676479727A74357366703775646D37687537367568377932366E6634646675796C71616266336F636C67747179353566627A6469'; 31 | 32 | $this->assertEquals($res, Utilities::convertStringToHex($str)); 33 | } 34 | 35 | public function testConvertHexToString(): void 36 | { 37 | $hex = '6578616D706C652E636F6D'; 38 | $res = 'example.com'; 39 | 40 | $this->assertEquals($res, Utilities::convertHexToString($hex)); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /website/documentation.twig: -------------------------------------------------------------------------------- 1 | {% extends "default.twig" %} 2 | 3 | {% block content %} 4 | 5 |
6 | 7 | 26 | 27 |
28 | {{ content|raw }} 29 |
30 | 31 |
32 | 33 | {% endblock %} -------------------------------------------------------------------------------- /website/fonts/FontAwesome.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlexanderBuzz/xrpl-php/2f79814df8263babc7bcb13b1bbdfa06d6c8b912/website/fonts/FontAwesome.otf -------------------------------------------------------------------------------- /website/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlexanderBuzz/xrpl-php/2f79814df8263babc7bcb13b1bbdfa06d6c8b912/website/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /website/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlexanderBuzz/xrpl-php/2f79814df8263babc7bcb13b1bbdfa06d6c8b912/website/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /website/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlexanderBuzz/xrpl-php/2f79814df8263babc7bcb13b1bbdfa06d6c8b912/website/fonts/fontawesome-webfont.woff --------------------------------------------------------------------------------