From 7ef0f4be7571f1a829e088435365a1f4732fbe27 Mon Sep 17 00:00:00 2001 From: Neto Date: Sun, 18 Oct 2026 17:47:37 +1030 Subject: [PATCH 1/3] Updates --- .gitattributes | 4 + .github/workflows/ci.yml | 78 ++++ .gitignore | 4 +- .php-cs-fixer.dist.php | 12 + CHANGELOG.md | 3 + CONTRIBUTING.md | 14 +- composer.json | 16 + examples/createAddress.php | 2 +- examples/generateWallet.php | 2 +- examples/getWalletByAddress.php | 2 +- examples/receiveWebhook.php | 2 +- examples/sendTransaction.php | 2 +- examples/sendTransactionToMany.php | 2 +- phpstan-baseline.neon | 607 +++++++++++++++++++++++++++++ phpstan.neon.dist | 9 + phpunit.xml.dist | 19 + src/BitGoExpress.php | 115 +++--- src/BitGoSDK.php | 291 ++++++++------ src/Enum/AddressType.php | 16 +- src/Enum/CurrencyCode.php | 12 +- tests/SmokeTest.php | 33 ++ 21 files changed, 1054 insertions(+), 191 deletions(-) create mode 100644 .github/workflows/ci.yml create mode 100644 .php-cs-fixer.dist.php create mode 100644 phpstan-baseline.neon create mode 100644 phpstan.neon.dist create mode 100644 phpunit.xml.dist create mode 100644 tests/SmokeTest.php diff --git a/.gitattributes b/.gitattributes index b20c76b..19f06a0 100644 --- a/.gitattributes +++ b/.gitattributes @@ -11,3 +11,7 @@ /.editorconfig export-ignore /.gitattributes export-ignore /.gitignore export-ignore +/.php-cs-fixer.dist.php export-ignore +/phpstan.neon.dist export-ignore +/phpstan-baseline.neon export-ignore +/phpunit.xml.dist export-ignore diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..1a1f35d --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,78 @@ +name: CI + +on: + push: + branches: [main] + pull_request: + workflow_dispatch: + +permissions: + contents: read + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + lint: + name: Lint (PHP ${{ matrix.php }}) + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + php: ['7.4', '8.0', '8.1', '8.2', '8.3', '8.4', '8.5'] + steps: + - uses: actions/checkout@v4 + - uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + coverage: none + tools: none + - name: Check syntax + run: find src tests examples -name '*.php' -print0 | xargs -0 -n1 php -l + + phpstan: + name: PHPStan + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: shivammathur/setup-php@v2 + with: + php-version: '8.4' + extensions: curl, bcmath + coverage: none + - uses: ramsey/composer-install@v3 + - run: vendor/bin/phpstan analyse --no-progress --error-format=github + + cs: + name: Coding standard + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: shivammathur/setup-php@v2 + with: + php-version: '8.4' + coverage: none + - uses: ramsey/composer-install@v3 + - run: vendor/bin/php-cs-fixer fix --dry-run --diff --show-progress=none + + phpunit: + name: PHPUnit (PHP ${{ matrix.php }}, ${{ matrix.dependencies }}) + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + php: ['7.4', '8.0', '8.1', '8.2', '8.3', '8.4', '8.5'] + dependencies: [lowest, highest] + steps: + - uses: actions/checkout@v4 + - uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + extensions: curl, bcmath + coverage: none + ini-values: error_reporting=-1, display_errors=On + - uses: ramsey/composer-install@v3 + with: + dependency-versions: ${{ matrix.dependencies }} + - run: vendor/bin/phpunit diff --git a/.gitignore b/.gitignore index f5654bb..c9bec69 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ /vendor composer.lock -/local_tests/* \ No newline at end of file +/local_tests/* +.phpunit.result.cache +.php-cs-fixer.cache diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php new file mode 100644 index 0000000..2c61dc7 --- /dev/null +++ b/.php-cs-fixer.dist.php @@ -0,0 +1,12 @@ +in([__DIR__ . '/src', __DIR__ . '/tests', __DIR__ . '/examples']); + +return (new PhpCsFixer\Config()) + ->setRules([ + '@PSR12' => true, + // Constant visibility needs PHP 7.1. Add 'const' back once the minimum PHP is raised to 7.4. + 'modifier_keywords' => ['elements' => ['method', 'property']], + ]) + ->setFinder($finder); diff --git a/CHANGELOG.md b/CHANGELOG.md index cd57f8d..9a12863 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,10 +12,13 @@ Entries for 2.2.3 and earlier were reconstructed from the git history in October - `CHANGELOG.md`, `SECURITY.md` and a full `CONTRIBUTING.md` (branch model, local setup, coding style, tests and release process). - `.editorconfig` and `.gitattributes`. +- Dev tooling: PHPUnit 9.6, PHPStan (level 6, with a baseline for the existing code) and PHP-CS-Fixer (PSR-12). +- A GitHub Actions CI workflow: `php -l` and PHPUnit on PHP 7.4 to 8.5 with lowest and highest dependencies, plus PHPStan and a coding-standard check. ### Changed - The project is now licensed under MIT. 2.2.3 and earlier were released under GPL-3.0. +- `src/` and `examples/` were reformatted to PSR-12. This is whitespace and brace placement only, with no behaviour change. - Composer dist archives no longer include `tests/`, `examples/`, `docs/` or dotfiles. The examples are still available in the repository. ## [2.2.3] - 2022-06-29 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 4de0a93..b57cfcb 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -50,26 +50,30 @@ cd BitGoSDK-PHP composer install ``` -`composer install` only generates the autoloader for now, because there are no dev dependencies yet. +`composer install` also installs the dev tools: PHPUnit, PHPStan and PHP-CS-Fixer. ## Coding style - Follow the style of the surrounding code: 4-space indentation, LF line endings, UTF-8 and a final newline. [.editorconfig](.editorconfig) sets these up for most editors. -- New code should follow [PSR-12](https://www.php-fig.org/psr/psr-12/). 2.3.0 adds PHP-CS-Fixer to enforce it. Until then, don't reformat code you aren't otherwise changing, so diffs stay reviewable. +- Code must follow [PSR-12](https://www.php-fig.org/psr/psr-12/). CI enforces it with PHP-CS-Fixer. Run `vendor/bin/php-cs-fixer fix` before you push. - 2.x changes must not break the public API. Don't rename or remove public methods or reorder their parameters. Widening a type (for example `int` to `int|string`) is fine. Breaking changes go to 3.x. - Code must still run on the minimum PHP version in `composer.json`. Don't use syntax or functions newer than that. - Give every public method a docblock with a short description, `@param` lines and `@return`, like the existing methods. ## Running tests -There's no automated test suite yet. 2.3.0 adds PHPUnit, PHPStan and CI, and this section will be updated with the `composer test` workflow. Until then: +CI runs these checks on every pull request. PHPUnit and `php -l` run on PHP 7.4 to 8.5, and PHPUnit runs with both the lowest and the highest allowed dependencies. -1. Check every PHP file for syntax errors: +1. Run the same checks locally: ```sh - find src examples -name '*.php' -exec php -l {} \; + vendor/bin/phpunit + vendor/bin/phpstan analyse + vendor/bin/php-cs-fixer fix --dry-run --diff ``` + PHPStan runs at level 6 against a baseline (`phpstan-baseline.neon`) of the errors in the existing code. Don't add new entries to it. When a fix removes an error, regenerate the baseline with `vendor/bin/phpstan analyse --generate-baseline phpstan-baseline.neon`. + 2. Exercise your change against BitGo **testnet**. Copy the relevant script from `examples/` into `local_tests/` (which is gitignored), fill in your testnet token and wallet ID there, and run it from the repository root: ```sh diff --git a/composer.json b/composer.json index 45ab774..edb23d5 100644 --- a/composer.json +++ b/composer.json @@ -18,9 +18,25 @@ } }, + "autoload-dev": { + "psr-4": { + "neto737\\BitGoSDK\\Tests\\": "tests/" + } + }, + "require": { "php": ">=7.0", "ext-curl": "*", "ext-bcmath": "*" + }, + + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.95", + "phpstan/phpstan": "^2.1", + "phpunit/phpunit": "^9.6.33" + }, + + "config": { + "sort-packages": true } } diff --git a/examples/createAddress.php b/examples/createAddress.php index c131767..fe6cee7 100644 --- a/examples/createAddress.php +++ b/examples/createAddress.php @@ -11,4 +11,4 @@ $bitgo->walletId = 'WALLET_ID_HERE'; $createAddress = $bitgo->createWalletAddress(); -var_dump($createAddress); \ No newline at end of file +var_dump($createAddress); diff --git a/examples/generateWallet.php b/examples/generateWallet.php index 5f9dcfa..3cc2856 100644 --- a/examples/generateWallet.php +++ b/examples/generateWallet.php @@ -13,4 +13,4 @@ $bitgoExpress->accessToken = 'YOUR_API_KEY_HERE'; $generateWallet = $bitgoExpress->generateWallet('LABEL_HERE', 'CREATE_A_NEW_PASSPHRASE_HERE'); -var_dump($generateWallet); \ No newline at end of file +var_dump($generateWallet); diff --git a/examples/getWalletByAddress.php b/examples/getWalletByAddress.php index 5c85282..04ee2ad 100644 --- a/examples/getWalletByAddress.php +++ b/examples/getWalletByAddress.php @@ -10,4 +10,4 @@ $bitgo = new BitGoSDK('YOUR_API_KEY_HERE', $coin, true); $getWalletByAddress = $bitgo->getWalletByAddress('WALLET_ADDRESS_HERE'); -var_dump($getWalletByAddress); \ No newline at end of file +var_dump($getWalletByAddress); diff --git a/examples/receiveWebhook.php b/examples/receiveWebhook.php index 106f1a3..bee7a7e 100644 --- a/examples/receiveWebhook.php +++ b/examples/receiveWebhook.php @@ -22,4 +22,4 @@ //YOU ARE RECEIVING A TRANSACTION... } else { //YOU ARE SENDING A TRANSACTION... -} \ No newline at end of file +} diff --git a/examples/sendTransaction.php b/examples/sendTransaction.php index 72dde95..809e3f0 100644 --- a/examples/sendTransaction.php +++ b/examples/sendTransaction.php @@ -30,4 +30,4 @@ $amount = BitGoSDK::toSatoshi($value_in_btc); $sendTransaction = $bitgoExpress->sendTransaction('DESTINATION_ADDRESS', $amount, 'YOUR_WALLET_PASSPHRASE'); -var_dump($sendTransaction); \ No newline at end of file +var_dump($sendTransaction); diff --git a/examples/sendTransactionToMany.php b/examples/sendTransactionToMany.php index a164b99..ae5627d 100644 --- a/examples/sendTransactionToMany.php +++ b/examples/sendTransactionToMany.php @@ -26,7 +26,7 @@ /** * $sendTo array needs to be a multidimensional array * All amounts in this array needs to be integer (int) values - * If you need convert bitcoin value into satoshi value just use toSatoshi function + * If you need convert bitcoin value into satoshi value just use toSatoshi function */ $sendTo = [ [ diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon new file mode 100644 index 0000000..e6129d5 --- /dev/null +++ b/phpstan-baseline.neon @@ -0,0 +1,607 @@ +parameters: + ignoreErrors: + - + message: '#^Access to an undefined property neto737\\BitGoSDK\\BitGoExpress\:\:\$coin\.$#' + identifier: property.notFound + count: 37 + path: src/BitGoExpress.php + + - + message: '#^Access to an undefined property neto737\\BitGoSDK\\BitGoExpress\:\:\$hostname\.$#' + identifier: property.notFound + count: 1 + path: src/BitGoExpress.php + + - + message: '#^Access to an undefined property neto737\\BitGoSDK\\BitGoExpress\:\:\$port\.$#' + identifier: property.notFound + count: 1 + path: src/BitGoExpress.php + + - + message: '#^Method neto737\\BitGoSDK\\BitGoExpress\:\:__execute\(\) has no return type specified\.$#' + identifier: missingType.return + count: 1 + path: src/BitGoExpress.php + + - + message: '#^Method neto737\\BitGoSDK\\BitGoExpress\:\:acceptWalletShare\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: src/BitGoExpress.php + + - + message: '#^Method neto737\\BitGoSDK\\BitGoExpress\:\:addWallet\(\) has parameter \$keys with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: src/BitGoExpress.php + + - + message: '#^Method neto737\\BitGoSDK\\BitGoExpress\:\:addWallet\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: src/BitGoExpress.php + + - + message: '#^Method neto737\\BitGoSDK\\BitGoExpress\:\:buildTransaction\(\) has parameter \$recipients with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: src/BitGoExpress.php + + - + message: '#^Method neto737\\BitGoSDK\\BitGoExpress\:\:buildTransaction\(\) has parameter \$unspents with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: src/BitGoExpress.php + + - + message: '#^Method neto737\\BitGoSDK\\BitGoExpress\:\:consolidateWalletUnspents\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: src/BitGoExpress.php + + - + message: '#^Method neto737\\BitGoSDK\\BitGoExpress\:\:createKeychain\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: src/BitGoExpress.php + + - + message: '#^Method neto737\\BitGoSDK\\BitGoExpress\:\:funoutWalletUnspents\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: src/BitGoExpress.php + + - + message: '#^Method neto737\\BitGoSDK\\BitGoExpress\:\:generateWallet\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: src/BitGoExpress.php + + - + message: '#^Method neto737\\BitGoSDK\\BitGoExpress\:\:login\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: src/BitGoExpress.php + + - + message: '#^Method neto737\\BitGoSDK\\BitGoExpress\:\:ping\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: src/BitGoExpress.php + + - + message: '#^Method neto737\\BitGoSDK\\BitGoExpress\:\:sendBuildTransaction\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: src/BitGoExpress.php + + - + message: '#^Method neto737\\BitGoSDK\\BitGoExpress\:\:sendTransaction\(\) has parameter \$unspents with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: src/BitGoExpress.php + + - + message: '#^Method neto737\\BitGoSDK\\BitGoExpress\:\:sendTransaction\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: src/BitGoExpress.php + + - + message: '#^Method neto737\\BitGoSDK\\BitGoExpress\:\:sendTransactionToMany\(\) has parameter \$recipients with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: src/BitGoExpress.php + + - + message: '#^Method neto737\\BitGoSDK\\BitGoExpress\:\:sendTransactionToMany\(\) has parameter \$unspents with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: src/BitGoExpress.php + + - + message: '#^Method neto737\\BitGoSDK\\BitGoExpress\:\:sendTransactionToMany\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: src/BitGoExpress.php + + - + message: '#^Method neto737\\BitGoSDK\\BitGoExpress\:\:shareWallet\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: src/BitGoExpress.php + + - + message: '#^Method neto737\\BitGoSDK\\BitGoExpress\:\:sweep\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: src/BitGoExpress.php + + - + message: '#^Method neto737\\BitGoSDK\\BitGoExpress\:\:updatePendingApproval\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: src/BitGoExpress.php + + - + message: '#^Method neto737\\BitGoSDK\\BitGoExpress\:\:verifyAddress\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: src/BitGoExpress.php + + - + message: '#^Property neto737\\BitGoSDK\\BitGoExpress\:\:\$APIEndpoint has no type specified\.$#' + identifier: missingType.property + count: 1 + path: src/BitGoExpress.php + + - + message: '#^Property neto737\\BitGoSDK\\BitGoExpress\:\:\$AuthAPIEndpoint has no type specified\.$#' + identifier: missingType.property + count: 1 + path: src/BitGoExpress.php + + - + message: '#^Property neto737\\BitGoSDK\\BitGoExpress\:\:\$UTXObased has no type specified\.$#' + identifier: missingType.property + count: 1 + path: src/BitGoExpress.php + + - + message: '#^Property neto737\\BitGoSDK\\BitGoExpress\:\:\$accessToken has no type specified\.$#' + identifier: missingType.property + count: 1 + path: src/BitGoExpress.php + + - + message: '#^Property neto737\\BitGoSDK\\BitGoExpress\:\:\$login has no type specified\.$#' + identifier: missingType.property + count: 1 + path: src/BitGoExpress.php + + - + message: '#^Property neto737\\BitGoSDK\\BitGoExpress\:\:\$params has no type specified\.$#' + identifier: missingType.property + count: 1 + path: src/BitGoExpress.php + + - + message: '#^Property neto737\\BitGoSDK\\BitGoExpress\:\:\$url has no type specified\.$#' + identifier: missingType.property + count: 1 + path: src/BitGoExpress.php + + - + message: '#^Property neto737\\BitGoSDK\\BitGoExpress\:\:\$walletId has no type specified\.$#' + identifier: missingType.property + count: 1 + path: src/BitGoExpress.php + + - + message: '#^Access to an undefined property neto737\\BitGoSDK\\BitGoSDK\:\:\$accessToken\.$#' + identifier: property.notFound + count: 2 + path: src/BitGoSDK.php + + - + message: '#^Access to an undefined property neto737\\BitGoSDK\\BitGoSDK\:\:\$coin\.$#' + identifier: property.notFound + count: 11 + path: src/BitGoSDK.php + + - + message: '#^Access to an undefined property neto737\\BitGoSDK\\BitGoSDK\:\:\$testNet\.$#' + identifier: property.notFound + count: 2 + path: src/BitGoSDK.php + + - + message: '#^Method neto737\\BitGoSDK\\BitGoSDK\:\:__execute\(\) has no return type specified\.$#' + identifier: missingType.return + count: 1 + path: src/BitGoSDK.php + + - + message: '#^Method neto737\\BitGoSDK\\BitGoSDK\:\:addBlockWebhook\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: src/BitGoSDK.php + + - + message: '#^Method neto737\\BitGoSDK\\BitGoSDK\:\:addKeychain\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: src/BitGoSDK.php + + - + message: '#^Method neto737\\BitGoSDK\\BitGoSDK\:\:addUserWebhook\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: src/BitGoSDK.php + + - + message: '#^Method neto737\\BitGoSDK\\BitGoSDK\:\:addWalletWebhook\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: src/BitGoSDK.php + + - + message: '#^Method neto737\\BitGoSDK\\BitGoSDK\:\:cancelWalletShare\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: src/BitGoSDK.php + + - + message: '#^Method neto737\\BitGoSDK\\BitGoSDK\:\:createBackupKeychain\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: src/BitGoSDK.php + + - + message: '#^Method neto737\\BitGoSDK\\BitGoSDK\:\:createBitGoKeychain\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: src/BitGoSDK.php + + - + message: '#^Method neto737\\BitGoSDK\\BitGoSDK\:\:createWalletAddress\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: src/BitGoSDK.php + + - + message: '#^Method neto737\\BitGoSDK\\BitGoSDK\:\:estimateTransactionFees\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: src/BitGoSDK.php + + - + message: '#^Method neto737\\BitGoSDK\\BitGoSDK\:\:freezeWallet\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: src/BitGoSDK.php + + - + message: '#^Method neto737\\BitGoSDK\\BitGoSDK\:\:getCurrentUserProfile\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: src/BitGoSDK.php + + - + message: '#^Method neto737\\BitGoSDK\\BitGoSDK\:\:getKeychain\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: src/BitGoSDK.php + + - + message: '#^Method neto737\\BitGoSDK\\BitGoSDK\:\:getMarketPriceData\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: src/BitGoSDK.php + + - + message: '#^Method neto737\\BitGoSDK\\BitGoSDK\:\:getMaximumSpendable\(\) has invalid return type neto737\\BitGoSDK\\type\.$#' + identifier: class.notFound + count: 1 + path: src/BitGoSDK.php + + - + message: '#^Method neto737\\BitGoSDK\\BitGoSDK\:\:getPendingApproval\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: src/BitGoSDK.php + + - + message: '#^Method neto737\\BitGoSDK\\BitGoSDK\:\:getSessionInfo\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: src/BitGoSDK.php + + - + message: '#^Method neto737\\BitGoSDK\\BitGoSDK\:\:getTotalBalances\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: src/BitGoSDK.php + + - + message: '#^Method neto737\\BitGoSDK\\BitGoSDK\:\:getWallet\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: src/BitGoSDK.php + + - + message: '#^Method neto737\\BitGoSDK\\BitGoSDK\:\:getWalletAddress\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: src/BitGoSDK.php + + - + message: '#^Method neto737\\BitGoSDK\\BitGoSDK\:\:getWalletAddresses\(\) has parameter \$chains with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: src/BitGoSDK.php + + - + message: '#^Method neto737\\BitGoSDK\\BitGoSDK\:\:getWalletAddresses\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: src/BitGoSDK.php + + - + message: '#^Method neto737\\BitGoSDK\\BitGoSDK\:\:getWalletByAddress\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: src/BitGoSDK.php + + - + message: '#^Method neto737\\BitGoSDK\\BitGoSDK\:\:getWalletShare\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: src/BitGoSDK.php + + - + message: '#^Method neto737\\BitGoSDK\\BitGoSDK\:\:getWalletTransaction\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: src/BitGoSDK.php + + - + message: '#^Method neto737\\BitGoSDK\\BitGoSDK\:\:getWalletTransactions\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: src/BitGoSDK.php + + - + message: '#^Method neto737\\BitGoSDK\\BitGoSDK\:\:getWalletTransfer\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: src/BitGoSDK.php + + - + message: '#^Method neto737\\BitGoSDK\\BitGoSDK\:\:getWalletTransferBySequenceId\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: src/BitGoSDK.php + + - + message: '#^Method neto737\\BitGoSDK\\BitGoSDK\:\:getWebhookPayload\(\) has invalid return type neto737\\BitGoSDK\\type\.$#' + identifier: class.notFound + count: 1 + path: src/BitGoSDK.php + + - + message: '#^Method neto737\\BitGoSDK\\BitGoSDK\:\:getWebhookPayload\(\) should return neto737\\BitGoSDK\\type but returns string\|false\.$#' + identifier: return.type + count: 1 + path: src/BitGoSDK.php + + - + message: '#^Method neto737\\BitGoSDK\\BitGoSDK\:\:listBlockWebhooks\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: src/BitGoSDK.php + + - + message: '#^Method neto737\\BitGoSDK\\BitGoSDK\:\:listKeychains\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: src/BitGoSDK.php + + - + message: '#^Method neto737\\BitGoSDK\\BitGoSDK\:\:listPendingApprovals\(\) has invalid return type neto737\\BitGoSDK\\type\.$#' + identifier: class.notFound + count: 1 + path: src/BitGoSDK.php + + - + message: '#^Method neto737\\BitGoSDK\\BitGoSDK\:\:listUserWebhooks\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: src/BitGoSDK.php + + - + message: '#^Method neto737\\BitGoSDK\\BitGoSDK\:\:listWalletShares\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: src/BitGoSDK.php + + - + message: '#^Method neto737\\BitGoSDK\\BitGoSDK\:\:listWalletTransfers\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: src/BitGoSDK.php + + - + message: '#^Method neto737\\BitGoSDK\\BitGoSDK\:\:listWalletUnspents\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: src/BitGoSDK.php + + - + message: '#^Method neto737\\BitGoSDK\\BitGoSDK\:\:listWalletWebhooks\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: src/BitGoSDK.php + + - + message: '#^Method neto737\\BitGoSDK\\BitGoSDK\:\:listWallets\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: src/BitGoSDK.php + + - + message: '#^Method neto737\\BitGoSDK\\BitGoSDK\:\:lockSession\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: src/BitGoSDK.php + + - + message: '#^Method neto737\\BitGoSDK\\BitGoSDK\:\:logout\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: src/BitGoSDK.php + + - + message: '#^Method neto737\\BitGoSDK\\BitGoSDK\:\:removeBlockWebhook\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: src/BitGoSDK.php + + - + message: '#^Method neto737\\BitGoSDK\\BitGoSDK\:\:removePolicyRule\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: src/BitGoSDK.php + + - + message: '#^Method neto737\\BitGoSDK\\BitGoSDK\:\:removeUserWebhook\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: src/BitGoSDK.php + + - + message: '#^Method neto737\\BitGoSDK\\BitGoSDK\:\:removeWalletUser\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: src/BitGoSDK.php + + - + message: '#^Method neto737\\BitGoSDK\\BitGoSDK\:\:removeWalletWebhook\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: src/BitGoSDK.php + + - + message: '#^Method neto737\\BitGoSDK\\BitGoSDK\:\:resendWalletShareInvite\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: src/BitGoSDK.php + + - + message: '#^Method neto737\\BitGoSDK\\BitGoSDK\:\:setRequestIP\(\) has no return type specified\.$#' + identifier: missingType.return + count: 1 + path: src/BitGoSDK.php + + - + message: '#^Method neto737\\BitGoSDK\\BitGoSDK\:\:setVelocityPolicyRule\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: src/BitGoSDK.php + + - + message: '#^Method neto737\\BitGoSDK\\BitGoSDK\:\:simulateUserWebhook\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: src/BitGoSDK.php + + - + message: '#^Method neto737\\BitGoSDK\\BitGoSDK\:\:simulateWalletWebhook\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: src/BitGoSDK.php + + - + message: '#^Method neto737\\BitGoSDK\\BitGoSDK\:\:toBTC\(\) should return float but returns string\.$#' + identifier: return.type + count: 1 + path: src/BitGoSDK.php + + - + message: '#^Method neto737\\BitGoSDK\\BitGoSDK\:\:unlockSession\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: src/BitGoSDK.php + + - + message: '#^Method neto737\\BitGoSDK\\BitGoSDK\:\:updateVelocityPolicyRule\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: src/BitGoSDK.php + + - + message: '#^Method neto737\\BitGoSDK\\BitGoSDK\:\:updateWalletAddress\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: src/BitGoSDK.php + + - + message: '#^PHPDoc tag @param references unknown parameter\: \$sortOrder$#' + identifier: parameter.notFound + count: 1 + path: src/BitGoSDK.php + + - + message: '#^Parameter \#1 \$left_operand of function bcdiv expects numeric\-string, int given\.$#' + identifier: argument.type + count: 1 + path: src/BitGoSDK.php + + - + message: '#^Parameter \#2 \$right_operand of function bcdiv expects numeric\-string, 100000000 given\.$#' + identifier: argument.type + count: 1 + path: src/BitGoSDK.php + + - + message: '#^Parameter \#2 \$right_operand of function bcmul expects numeric\-string, 100000000 given\.$#' + identifier: argument.type + count: 1 + path: src/BitGoSDK.php + + - + message: '#^Property neto737\\BitGoSDK\\BitGoSDK\:\:\$APIEndpoint has no type specified\.$#' + identifier: missingType.property + count: 1 + path: src/BitGoSDK.php + + - + message: '#^Property neto737\\BitGoSDK\\BitGoSDK\:\:\$AuthAPIEndpoint has no type specified\.$#' + identifier: missingType.property + count: 1 + path: src/BitGoSDK.php + + - + message: '#^Property neto737\\BitGoSDK\\BitGoSDK\:\:\$params has no type specified\.$#' + identifier: missingType.property + count: 1 + path: src/BitGoSDK.php + + - + message: '#^Property neto737\\BitGoSDK\\BitGoSDK\:\:\$requestIP has no type specified\.$#' + identifier: missingType.property + count: 1 + path: src/BitGoSDK.php + + - + message: '#^Property neto737\\BitGoSDK\\BitGoSDK\:\:\$url has no type specified\.$#' + identifier: missingType.property + count: 1 + path: src/BitGoSDK.php + + - + message: '#^Property neto737\\BitGoSDK\\BitGoSDK\:\:\$walletId has no type specified\.$#' + identifier: missingType.property + count: 1 + path: src/BitGoSDK.php diff --git a/phpstan.neon.dist b/phpstan.neon.dist new file mode 100644 index 0000000..2f93555 --- /dev/null +++ b/phpstan.neon.dist @@ -0,0 +1,9 @@ +includes: + - phpstan-baseline.neon + +parameters: + level: 6 + phpVersion: 70400 + paths: + - src + - tests diff --git a/phpunit.xml.dist b/phpunit.xml.dist new file mode 100644 index 0000000..1e112da --- /dev/null +++ b/phpunit.xml.dist @@ -0,0 +1,19 @@ + + + + + tests + + + + + src + + + diff --git a/src/BitGoExpress.php b/src/BitGoExpress.php index 39c9b67..9e840c6 100644 --- a/src/BitGoExpress.php +++ b/src/BitGoExpress.php @@ -3,9 +3,9 @@ /** * ____ _ _ ____ ____ ____ _ __ * | __ )(_) |_ / ___| ___/ ___|| _ \| |/ / - * | _ \| | __| | _ / _ \___ \| | | | ' / - * | |_) | | |_| |_| | (_) |__) | |_| | . \ - * |____/|_|\__|\____|\___/____/|____/|_|\_\ + * | _ \| | __| | _ / _ \___ \| | | | ' / + * | |_) | | |_| |_| | (_) |__) | |_| | . \ + * |____/|_|\__|\____|\___/____/|____/|_|\_\ * * @package BitGoSDK PHP * @author Neto Melo @@ -17,8 +17,8 @@ use neto737\BitGoSDK\Enum\CurrencyCode; -class BitGoExpress { - +class BitGoExpress +{ private $APIEndpoint = null; private $AuthAPIEndpoint = null; private $url = null; @@ -30,13 +30,14 @@ class BitGoExpress { /** * BitGoExpress Initialization - * + * * @param string $hostname Set the hostname of your BitGo Express instance * @param int $port Set the port of your BitGo Express instance * @param string $coin Select the coin what you want to use with the BitGOSDK (use CurrencyCode class to select) * @throws \Exception */ - public function __construct(string $hostname, int $port, string $coin = CurrencyCode::BITCOIN) { + public function __construct(string $hostname, int $port, string $coin = CurrencyCode::BITCOIN) + { $this->hostname = $hostname; $this->port = $port; $this->coin = $coin; @@ -46,14 +47,15 @@ public function __construct(string $hostname, int $port, string $coin = Currency /** * Get a token for first-party access to the BitGo API. First-party access is only intended for users accessing their own BitGo accounts. - * + * * @param string $email The user’s email address * @param string $password The user’s password * @param string $otp The 2nd-factor-authentication token * @param bool $extensible True if the session is supposed to be extensible beyond a one-hour duration. * @return array */ - public function login(string $email, string $password, string $otp, bool $extensible = null) { + public function login(string $email, string $password, string $otp, bool $extensible = null) + { $this->url = $this->AuthAPIEndpoint . '/user/login'; $this->params = [ 'email' => $email, @@ -67,17 +69,18 @@ public function login(string $email, string $password, string $otp, bool $extens /** * Ping bitgo express to ensure that it is still running. Unlike /ping, this does not try connecting to bitgo.com. - * + * * @return array */ - public function ping() { + public function ping() + { $this->url = $this->AuthAPIEndpoint . '/ping'; return $this->__execute('GET'); } /** * This API call creates a new wallet. - * + * * @param string $label Human-readable name for the wallet. * @param string $passphrase Passphrase to decrypt the wallet’s private key. * @param string $userKey Optional xpub to be used as the user key. @@ -89,7 +92,8 @@ public function ping() { * @param string $passcodeEncryptionCode Encryption code for wallet passphrase (used for lost passphrase recovery) * @return array */ - public function generateWallet(string $label, string $passphrase, string $userKey = null, string $backupXpub = null, string $backupXpubProvider = null, string $enterprise = null, bool $disableTransactionNotifications = null, int $gasPrice = null, string $passcodeEncryptionCode = null) { + public function generateWallet(string $label, string $passphrase, string $userKey = null, string $backupXpub = null, string $backupXpubProvider = null, string $enterprise = null, bool $disableTransactionNotifications = null, int $gasPrice = null, string $passcodeEncryptionCode = null) + { $this->url = $this->APIEndpoint . '/wallet/generate'; $this->params = [ 'label' => $label, @@ -108,7 +112,7 @@ public function generateWallet(string $label, string $passphrase, string $userKe /** * This API creates a new wallet for the user. * The keys to use with the new wallet (passed in the ‘keys’ parameter) must be registered with BitGo prior to using this API. - * + * * @param string $label Human-readable name for the wallet. * @param int $m Number of signatures required for wallet (must be 2). * @param int $n Number of total signers on wallet (must be 3). @@ -118,7 +122,8 @@ public function generateWallet(string $label, string $passphrase, string $userKe * @param bool $disableTransactionNotifications Will prevent wallet transaction notifications if set to true. * @return array */ - public function addWallet(string $label, int $m, int $n, array $keys, string $enterprise = null, bool $isCold = null, bool $disableTransactionNotifications = null) { + public function addWallet(string $label, int $m, int $n, array $keys, string $enterprise = null, bool $isCold = null, bool $disableTransactionNotifications = null) + { $this->url = $this->APIEndpoint . '/wallet'; $this->params = [ 'label' => $label, @@ -134,7 +139,7 @@ public function addWallet(string $label, int $m, int $n, array $keys, string $en /** * This API call allows you to create and send cryptocurrency to a destination address. - * + * * @param string $address Recipient address * @param int $amount Amount to be sent to the recipient * @param string $walletPassphrase The passphrase to be used to decrypt the user key on this wallet @@ -157,7 +162,8 @@ public function addWallet(string $label, int $m, int $n, array $keys, string $en * @param string $ledgerSequenceDelta Relative ledger height (in relation to the current ledger) that the transaction should be accepted in, whereafter it will be rejected. * @return array */ - public function sendTransaction(string $address, int $amount, string $walletPassphrase, string $prv = null, int $numBlocks = null, int $feeRate = null, string $comment = null, array $unspents = null, int $minConfirms = null, bool $enforceMinConfirmsForChange = null, int $targetWalletUnspents = null, bool $noSplitChange = null, int $minValue = null, int $maxValue = null, int $gasPrice = null, int $gasLimit = null, int $sequenceId = null, bool $segwit = null, int $lastLedgerSequence = null, string $ledgerSequenceDelta = null) { + public function sendTransaction(string $address, int $amount, string $walletPassphrase, string $prv = null, int $numBlocks = null, int $feeRate = null, string $comment = null, array $unspents = null, int $minConfirms = null, bool $enforceMinConfirmsForChange = null, int $targetWalletUnspents = null, bool $noSplitChange = null, int $minValue = null, int $maxValue = null, int $gasPrice = null, int $gasLimit = null, int $sequenceId = null, bool $segwit = null, int $lastLedgerSequence = null, string $ledgerSequenceDelta = null) + { $this->url = $this->APIEndpoint . '/wallet/' . $this->walletId . '/sendcoins'; $this->params = [ 'address' => $address, @@ -185,9 +191,9 @@ public function sendTransaction(string $address, int $amount, string $walletPass } /** - * This API call allows you to create a transaction and send to multiple addresses. + * This API call allows you to create a transaction and send to multiple addresses. * This may be useful if you schedule outgoing transactions in bulk, as you will be able to process multiple recipients and lower the aggregate amount of blockchain fees paid. - * + * * @param array $recipients Array of recipient objects and the amount to send to each e.g. [{address: ‘38BKDNZbPcLogvVbcx2ekJ9E6Vv94DqDqw’, amount: 1500}, …] * @param string $walletPassphrase The passphrase to be used to decrypt the user key on this wallet * @param string $prv The private key in string form if the walletPassphrase is not available @@ -209,7 +215,8 @@ public function sendTransaction(string $address, int $amount, string $walletPass * @param string $ledgerSequenceDelta Relative ledger height (in relation to the current ledger) that the transaction should be accepted in, whereafter it will be rejected. * @return array */ - public function sendTransactionToMany(array $recipients, string $walletPassphrase, string $prv = null, int $numBlocks = null, int $feeRate = null, string $comment = null, array $unspents = null, int $minConfirms = null, bool $enforceMinConfirmsForChange = null, int $targetWalletUnspents = null, bool $noSplitChange = null, int $minValue = null, int $maxValue = null, int $gasPrice = null, int $gasLimit = null, int $sequenceId = null, bool $segwit = null, int $lastLedgerSequence = null, string $ledgerSequenceDelta = null) { + public function sendTransactionToMany(array $recipients, string $walletPassphrase, string $prv = null, int $numBlocks = null, int $feeRate = null, string $comment = null, array $unspents = null, int $minConfirms = null, bool $enforceMinConfirmsForChange = null, int $targetWalletUnspents = null, bool $noSplitChange = null, int $minValue = null, int $maxValue = null, int $gasPrice = null, int $gasLimit = null, int $sequenceId = null, bool $segwit = null, int $lastLedgerSequence = null, string $ledgerSequenceDelta = null) + { $this->url = $this->APIEndpoint . '/wallet/' . $this->walletId . '/sendmany'; $this->params = [ 'recipients' => $recipients, @@ -237,7 +244,7 @@ public function sendTransactionToMany(array $recipients, string $walletPassphras /** * This SDK call will consolidate the unspents that match the parameters, and consolidate them into the number specified by 'numUnspentsToMake'. - * + * * @param string $walletPassphrase Passphrase to decrypt the wallet’s private key. * @param int $numUnspentsToMake Number of outputs created by the consolidation transaction (Defaults to 1) * @param int $limit Number of unspents to select (Defaults to 25, Max is 200) @@ -251,7 +258,8 @@ public function sendTransactionToMany(array $recipients, string $walletPassphras * @param bool $enforceMinConfirmsForChange Apply the required confirmations set in minConfirms for change outputs * @return array */ - public function consolidateWalletUnspents(string $walletPassphrase, int $numUnspentsToMake = null, int $limit = null, int $minValue = null, int $maxValue = null, int $minHeight = null, int $feeRate = null, int $feeTxConfirmTarget = null, int $maxFeePercentage = null, int $minConfirms = null, bool $enforceMinConfirmsForChange = null) { + public function consolidateWalletUnspents(string $walletPassphrase, int $numUnspentsToMake = null, int $limit = null, int $minValue = null, int $maxValue = null, int $minHeight = null, int $feeRate = null, int $feeTxConfirmTarget = null, int $maxFeePercentage = null, int $minConfirms = null, bool $enforceMinConfirmsForChange = null) + { $this->url = $this->APIEndpoint . '/wallet/' . $this->walletId . '/consolidateunspents'; $this->params = [ 'walletPassphrase' => $walletPassphrase, @@ -271,7 +279,7 @@ public function consolidateWalletUnspents(string $walletPassphrase, int $numUnsp /** * This SDK call will fanout the unspents currently in the wallet that match the parameters, and use them as inputs to create more unspents. - * + * * @param string $walletPassphrase Passphrase to decrypt the wallet’s private key. * @param string $xprv The private key in string form if the walletPassphrase is not available * @param int $maxNumInputsToUse Number of unspents you want to use in the fanout transaction (Default 20, Max 80) @@ -286,7 +294,8 @@ public function consolidateWalletUnspents(string $walletPassphrase, int $numUnsp * @param int $feeTxConfirmTarget Fee rate is automatically chosen by targeting a transaction confirmation in this number of blocks (Only available on BTC, feeRate takes precedence if also set) * @return array */ - public function funoutWalletUnspents(string $walletPassphrase, string $xprv = null, int $maxNumInputsToUse = null, int $numUnspentsToMake = null, int $minValue = null, int $maxValue = null, int $minHeight = null, int $maxFeePercentage = null, int $minConfirms = null, bool $enforceMinConfirmsForChange = null, int $feeRate = null, int $feeTxConfirmTarget = null) { + public function funoutWalletUnspents(string $walletPassphrase, string $xprv = null, int $maxNumInputsToUse = null, int $numUnspentsToMake = null, int $minValue = null, int $maxValue = null, int $minHeight = null, int $maxFeePercentage = null, int $minConfirms = null, bool $enforceMinConfirmsForChange = null, int $feeRate = null, int $feeTxConfirmTarget = null) + { $this->url = $this->APIEndpoint . '/wallet/' . $this->walletId . '/fanoutunspents'; $this->params = [ 'walletPassphrase' => $walletPassphrase, @@ -307,7 +316,7 @@ public function funoutWalletUnspents(string $walletPassphrase, string $xprv = nu /** * his SDK call attempts to move all of the funds of the wallet into the address provided. - * + * * @param string $address The address to send all the funds in the wallet to. * @param string $walletPassphrase Passphrase to decrypt the wallet’s private key. * @param string $xprv The private key in string form if the walletPassphrase is not available @@ -320,7 +329,8 @@ public function funoutWalletUnspents(string $walletPassphrase, string $xprv = nu * @param string $ledgerSequenceDelta Relative ledger height (in relation to the current ledger) that the transaction should be accepted in, whereafter it will be rejected. * @return array */ - public function sweep(string $address, string $walletPassphrase, string $xprv = null, string $otp = null, int $feeRate = null, int $feeTxConfirmTarget = null, int $gasPrice = null, int $sequenceId = null, int $lastLedgerSequence = null, string $ledgerSequenceDelta = null) { + public function sweep(string $address, string $walletPassphrase, string $xprv = null, string $otp = null, int $feeRate = null, int $feeTxConfirmTarget = null, int $gasPrice = null, int $sequenceId = null, int $lastLedgerSequence = null, string $ledgerSequenceDelta = null) + { $this->url = $this->APIEndpoint . '/wallet/' . $this->walletId . '/sweep'; $this->params = [ 'address' => $address, @@ -339,7 +349,7 @@ public function sweep(string $address, string $walletPassphrase, string $xprv = /** * Create a transaction with the specified parameters. This builds a transaction object, but does not sign or send it. - * + * * @param array $recipients List of recipients in array * @param int $numBlocks Estimates the approximate fee per kilobyte necessary for a transaction confirmation within 'numBlocks' blocks. * @param int $feeRate Fee rate in satoshis/litoshis/atoms per kilobyte. @@ -355,7 +365,8 @@ public function sweep(string $address, string $walletPassphrase, string $xprv = * @param string $ledgerSequenceDelta Relative ledger height (in relation to the current ledger) that the transaction should be accepted in, whereafter it will be rejected. * @return object Returns the newly created transaction description object. */ - public function buildTransaction(array $recipients, int $numBlocks = null, int $feeRate = null, int $minConfirms = null, bool $enforceMinConfirmsForChange = null, array $unspents = null, int $targetWalletUnspents = null, bool $noSplitChange = null, int $minValue = null, int $maxValue = null, int $gasPrice = null, int $lastLedgerSequence = null, string $ledgerSequenceDelta = null) { + public function buildTransaction(array $recipients, int $numBlocks = null, int $feeRate = null, int $minConfirms = null, bool $enforceMinConfirmsForChange = null, array $unspents = null, int $targetWalletUnspents = null, bool $noSplitChange = null, int $minValue = null, int $maxValue = null, int $gasPrice = null, int $lastLedgerSequence = null, string $ledgerSequenceDelta = null) + { $this->url = $this->APIEndpoint . '/wallet/' . $this->walletId . '/tx/build'; $this->params = [ 'recipients' => $recipients, @@ -378,7 +389,7 @@ public function buildTransaction(array $recipients, int $numBlocks = null, int $ /** * Sign the given transaction with the specified keychain. All signing is done locally and can be performed offline. * Signing can happen two ways: with a prv argument representing the private key, or with keychain and walletPassphrase arguments (for signing with an encrypted private key). - * + * * @param object $txPrebuild The transaction description object, output from 'Build Transaction’ * @param string $prv The user private key * @param string $coldDerivationSeed The seed used to derive the signing key @@ -386,7 +397,8 @@ public function buildTransaction(array $recipients, int $numBlocks = null, int $ * @param string $walletPassphrase Passphrase to decrypt the user keychain * @return object The half-signed, serialized transaction hex */ - public function signBuildTransaction($txPrebuild, string $prv = null, string $coldDerivationSeed = null, $keychain = null, string $walletPassphrase = null) { + public function signBuildTransaction($txPrebuild, string $prv = null, string $coldDerivationSeed = null, $keychain = null, string $walletPassphrase = null) + { $this->url = $this->APIEndpoint . '/wallet/' . $this->walletId . '/signtx'; $this->params = [ 'txPrebuild' => $txPrebuild, @@ -400,14 +412,15 @@ public function signBuildTransaction($txPrebuild, string $prv = null, string $co /** * Submit a half-signed transaction. - * + * * @param object $halfSigned The half-signed info returned from 'Sign Transaction’ * @param string $otp The current 2FA code * @param string $txHex The half-signed, serialized transaction hex (alternative to halfSigned) * @param string $comment Any additional comment to attach to the transaaction * @return array */ - public function sendBuildTransaction($halfSigned, string $otp, string $txHex = null, string $comment = null) { + public function sendBuildTransaction($halfSigned, string $otp, string $txHex = null, string $comment = null) + { $this->url = $this->APIEndpoint . '/wallet/' . $this->walletId . '/tx/send'; $this->params = [ 'halfSigned' => $halfSigned, @@ -420,17 +433,18 @@ public function sendBuildTransaction($halfSigned, string $otp, string $txHex = n /** * Local client-side function to create a new keychain. - * + * * @return array */ - public function createKeychain() { + public function createKeychain() + { $this->url = $this->APIEndpoint . '/keychain/local'; return $this->__execute(); } /** * Sharing a wallet involves giving another user permission to use the wallet through BitGo. - * + * * @param string $email Email of the user to share the wallet with * @param string $permissions Comma-separated list of permissions, e.g. view,spend,admin * @param string $walletPassphrase Passphrase on the wallet being shared @@ -438,7 +452,8 @@ public function createKeychain() { * @param bool $disableEmail Set to true to prevent a notification email sent to the user added * @return array */ - public function shareWallet(string $email, string $permissions, string $walletPassphrase = null, bool $skipKeychain = null, bool $disableEmail = null) { + public function shareWallet(string $email, string $permissions, string $walletPassphrase = null, bool $skipKeychain = null, bool $disableEmail = null) + { $this->url = $this->APIEndpoint . '/wallet/' . $this->walletId . '/share'; $this->params = [ 'email' => $email, @@ -452,14 +467,15 @@ public function shareWallet(string $email, string $permissions, string $walletPa /** * Client-side operation to accept a wallet share. - * + * * @param string $walletShareId The incoming wallet share ID to accept * @param string $newWalletPassphrase The passphrase to set on the wallet, for use during future spends * @param string $userPassword The user’s password to decrypt the shared private key * @param string $overrideEncryptedPrv Set to an alternate encrypted prv if you wish to store an encrypted prv received out-of-band * @return array */ - public function acceptWalletShare(string $walletShareId, string $newWalletPassphrase = null, string $userPassword = null, string $overrideEncryptedPrv = null) { + public function acceptWalletShare(string $walletShareId, string $newWalletPassphrase = null, string $userPassword = null, string $overrideEncryptedPrv = null) + { $this->url = $this->APIEndpoint . '/walletshare/' . $walletShareId . '/acceptshare'; $this->params = [ 'walletShareId' => $walletShareId, @@ -472,13 +488,14 @@ public function acceptWalletShare(string $walletShareId, string $newWalletPassph /** * Update the state of a pending approval to either ‘approved’ or 'rejected'. Pending approvals are designed to be managed through our web UI. - * + * * @param string $pendingApprovalId Pending approval id. * @param string $state Approval * @param string $otp One Time Password * @return array */ - public function updatePendingApproval(string $pendingApprovalId, string $state, string $otp) { + public function updatePendingApproval(string $pendingApprovalId, string $state, string $otp) + { $this->url = $this->APIEndpoint . '/pendingapprovals/' . $pendingApprovalId; $this->params = [ 'state' => $state, @@ -489,12 +506,13 @@ public function updatePendingApproval(string $pendingApprovalId, string $state, /** * Symmetrically encrypt an arbitrary message with provided password - * + * * @param string $input Plaintext message which should be encrypted * @param string $password Password which should be used to encrypt message * @return string */ - public function encrypt(string $input, string $password) { + public function encrypt(string $input, string $password) + { $this->url = $this->AuthAPIEndpoint . '/encrypt'; $this->params = [ 'input' => $input, @@ -505,12 +523,13 @@ public function encrypt(string $input, string $password) { /** * Decrypt a ciphertext generated by encrypt route with provided password - * + * * @param string $input Ciphertext to decrypt * @param string $password Key which is used for decryption * @return string */ - public function decrypt(string $input, string $password) { + public function decrypt(string $input, string $password) + { $this->url = $this->AuthAPIEndpoint . '/decrypt'; $this->params = [ 'input' => $input, @@ -521,11 +540,12 @@ public function decrypt(string $input, string $password) { /** * Verify address for a given coin - * + * * @param string $address Address which should be verified for correct format * @return array */ - public function verifyAddress(string $address) { + public function verifyAddress(string $address) + { $this->url = $this->APIEndpoint . '/verifyaddress'; $this->params = [ 'address' => $address @@ -533,7 +553,8 @@ public function verifyAddress(string $address) { return $this->__execute(); } - private function __execute(string $requestType = 'POST', bool $array = true) { + private function __execute(string $requestType = 'POST', bool $array = true) + { $ch = curl_init($this->url); if ($requestType === 'POST') { curl_setopt($ch, CURLOPT_POST, true); diff --git a/src/BitGoSDK.php b/src/BitGoSDK.php index 7bbd6d6..3e457de 100644 --- a/src/BitGoSDK.php +++ b/src/BitGoSDK.php @@ -3,9 +3,9 @@ /** * ____ _ _ ____ ____ ____ _ __ * | __ )(_) |_ / ___| ___/ ___|| _ \| |/ / - * | _ \| | __| | _ / _ \___ \| | | | ' / - * | |_) | | |_| |_| | (_) |__) | |_| | . \ - * |____/|_|\__|\____|\___/____/|____/|_|\_\ + * | _ \| | __| | _ / _ \___ \| | | | ' / + * | |_) | | |_| |_| | (_) |__) | |_| | . \ + * |____/|_|\__|\____|\___/____/|____/|_|\_\ * * @package BitGoSDK PHP * @author Neto Melo @@ -18,8 +18,8 @@ use neto737\BitGoSDK\Enum\CurrencyCode; use neto737\BitGoSDK\Enum\AddressType; -class BitGoSDK { - +class BitGoSDK +{ const BITGO_PRODUCTION_API_ENDPOINT = 'https://app.bitgo.com/api/v2/'; const BITGO_TESTNET_API_ENDPOINT = 'https://app.bitgo-test.com/api/v2/'; @@ -32,13 +32,14 @@ class BitGoSDK { /** * BitGoSDK Initialization - * + * * @param string $accessToken Set your Access Token (API Key) * @param string $coin Select the coin what you want to use with the BitGOSDK (use CurrencyCode class to select) * @param bool $testNet Start instance as testnet (true or false), default is false * @throws \Exception */ - public function __construct(string $accessToken, string $coin = CurrencyCode::BITCOIN, bool $testNet = false) { + public function __construct(string $accessToken, string $coin = CurrencyCode::BITCOIN, bool $testNet = false) + { $this->accessToken = $accessToken; $this->coin = $coin; $this->testNet = $testNet; @@ -48,10 +49,11 @@ public function __construct(string $accessToken, string $coin = CurrencyCode::BI /** * Set the IP that will make requests on BitGo servers (useful feature to people who uses shared hosting) - * + * * @param string $ipAddress */ - public function setRequestIP(string $ipAddress) { + public function setRequestIP(string $ipAddress) + { if (!$this->testNet && filter_var($ipAddress, FILTER_VALIDATE_IP)) { $this->requestIP = $ipAddress; } @@ -59,62 +61,68 @@ public function setRequestIP(string $ipAddress) { /** * Converts value in satoshi to BTC value - * + * * @param int $amount amount in satoshi that you want to convert to BTC * @return float value converted to BTC */ - public static function toBTC(int $amount) { + public static function toBTC(int $amount) + { return sprintf('%.8f', bcdiv($amount, 100000000, 8)); } /** * Converts value in BTC to satoshi value - * + * * @param float $amount amount in BTC that you want to convert to satoshi * @return int value converted to satoshi */ - public static function toSatoshi(float $amount) { + public static function toSatoshi(float $amount) + { return (int) bcmul(sprintf('%.8f', $amount), 100000000, 0); } /** * This API call retrieves information about the current authenticated user. - * + * * @return array */ - public function getCurrentUserProfile() { + public function getCurrentUserProfile() + { $this->url = $this->AuthAPIEndpoint . 'user/me'; return $this->__execute('GET'); } /** * This API call retrieves information about the current session access token. - * + * * @return array */ - public function getSessionInfo() { + public function getSessionInfo() + { $this->url = $this->AuthAPIEndpoint . 'user/session'; return $this->__execute('GET'); } /** * Locks the current session, preventing future automated sends without a subsequent unlock (OTP will be required for the unlock). - * + * * @return array */ - public function lockSession() { + public function lockSession() + { $this->url = $this->AuthAPIEndpoint . 'user/lock'; return $this->__execute(); } /** * Unlock the current session, which is required for certain other sensitive API calls. - * + * * @param string $otp An OTP code for the account obtained using the second factor authentication device * @param int $duration Desired duration of the unlock in seconds (default=600, max=3600) * @return array */ - public function unlockSession(string $otp, int $duration = 600) { + public function unlockSession(string $otp, int $duration = 600) + { $this->url = $this->AuthAPIEndpoint . 'user/unlock'; $this->params = [ 'otp' => $otp, @@ -125,23 +133,25 @@ public function unlockSession(string $otp, int $duration = 600) { /** * Log out of the BitGo service. This will disable an access token. - * + * * @return array */ - public function logout() { + public function logout() + { $this->url = $this->AuthAPIEndpoint . 'user/logout'; return $this->__execute('GET'); } /** * This API call lists all of a user’s wallets for a given coin. - * + * * @param int $limit Max number of results in a single call. Defaults to 25. * @param string $prevId Continue iterating wallets from this prevId as provided by nextBatchPrevId in the previous list * @param bool $allTokens Gets details of all tokens associated with this wallet. Only valid for ETH/TETH * @return array */ - public function listWallets(int $limit = 25, string $prevId = null, bool $allTokens = false) { + public function listWallets(int $limit = 25, string $prevId = null, bool $allTokens = false) + { $this->url = $this->APIEndpoint . '/wallet'; $this->params = [ 'limit' => $limit, @@ -153,11 +163,12 @@ public function listWallets(int $limit = 25, string $prevId = null, bool $allTok /** * This API call retrieves wallet object information by the wallet ID. - * + * * @param bool $allTokens Gets details of all tokens associated with this wallet. Only valid for ETH/TETH * @return array */ - public function getWallet(bool $allTokens = false) { + public function getWallet(bool $allTokens = false) + { $this->url = $this->APIEndpoint . '/wallet/' . $this->walletId; $this->params = [ 'allTokens' => $this->coin === CurrencyCode::ETHEREUM || $this->coin === CurrencyCode::ETHEREUM_TESTNET ? $allTokens : null, @@ -167,23 +178,25 @@ public function getWallet(bool $allTokens = false) { /** * This API call retrieves wallet object information by an address belonging to the wallet. - * + * * @param string $walletAddress The address * @return array */ - public function getWalletByAddress(string $walletAddress) { + public function getWalletByAddress(string $walletAddress) + { $this->url = $this->APIEndpoint . '/wallet/address/' . $walletAddress; return $this->__execute('GET'); } /** * Retrieves a list of transfers, which correspond to the deposits and withdrawals of digital currency on a wallet. - * + * * @param string $prevId Continue iterating from this prevId (provided by nextBatchPrevId in the previous list) * @param bool $allTokens Gets transfers of all tokens associated with this wallet. Only valid for ETH/TETH. * @return array */ - public function listWalletTransfers(string $prevId = null, bool $allTokens = false) { + public function listWalletTransfers(string $prevId = null, bool $allTokens = false) + { $this->url = $this->APIEndpoint . '/wallet/' . $this->walletId . '/transfer'; $this->params = [ 'prevId' => $prevId, @@ -194,37 +207,40 @@ public function listWalletTransfers(string $prevId = null, bool $allTokens = fal /** * Wallet transfers represent digital currency sends and receives on your wallet. - * + * * @param string $transactionId ID of the wallet transfer * @return array */ - public function getWalletTransfer(string $transactionId) { + public function getWalletTransfer(string $transactionId) + { $this->url = $this->APIEndpoint . '/wallet/' . $this->walletId . '/transfer/' . $transactionId; return $this->__execute('GET'); } /** - * Get the transaction on a wallet sequence ID that was passed in when sending a transaction + * Get the transaction on a wallet sequence ID that was passed in when sending a transaction * (via Send Transaction or Send Transaction to Many). - * + * * @param string $sequenceId The unique id previously sent with an outgoing transaction * @return array */ - public function getWalletTransferBySequenceId(string $sequenceId) { + public function getWalletTransferBySequenceId(string $sequenceId) + { $this->url = $this->APIEndpoint . '/wallet/' . $this->walletId . '/transfer/sequenceId/' . $sequenceId; return $this->__execute('GET'); } /** * This API call is used to create a new receive address for your wallet, which enhances your privacy. - * + * * @param int $chain Specifies the address format, defaults to 0, use 10 for SegWit (only on BTC and BTG) * @param string $label Human-readable name for the address * @param int $gasPrice Custom gas price to be used for deployment of receive addresses (only for Ethereum) * @param bool $lowPriority Whether the deployment of the address forwarder contract should use a low priority fee key (ETH only) * @return array */ - public function createWalletAddress(int $chain = AddressType::P2SH_DEPOSIT, string $label = null, bool $lowPriority = false, int $gasPrice = null) { + public function createWalletAddress(int $chain = AddressType::P2SH_DEPOSIT, string $label = null, bool $lowPriority = false, int $gasPrice = null) + { $this->url = $this->APIEndpoint . '/wallet/' . $this->walletId . '/address'; $this->params = [ 'chain' => $chain, @@ -237,11 +253,12 @@ public function createWalletAddress(int $chain = AddressType::P2SH_DEPOSIT, stri /** * This API call is used to get information about a single wallet address. - * + * * @param string $addressOrId Valid address or address id of the wallet. * @return array */ - public function getWalletAddress(string $addressOrId, string $dt = null, string $memoId = null) { + public function getWalletAddress(string $addressOrId, string $dt = null, string $memoId = null) + { $this->url = $this->APIEndpoint . '/wallet/' . $this->walletId . '/address/' . $addressOrId; $this->params = [ 'dt' => $this->coin === CurrencyCode::RIPPLE ? $dt : null, @@ -252,12 +269,13 @@ public function getWalletAddress(string $addressOrId, string $dt = null, string /** * This API call is used to update fields on a wallet address. - * + * * @param string $addressOrId Valid address or address id of the wallet. * @param string $label Human-readable name for the address * @return array */ - public function updateWalletAddress(string $addressOrId, string $dt = null, string $memoId = null, string $label = null) { + public function updateWalletAddress(string $addressOrId, string $dt = null, string $memoId = null, string $label = null) + { $this->url = $this->APIEndpoint . '/wallet/' . $this->walletId . '/address/' . $addressOrId; $this->params = [ 'dt' => $this->coin === CurrencyCode::RIPPLE ? $dt : null, @@ -269,13 +287,14 @@ public function updateWalletAddress(string $addressOrId, string $dt = null, stri /** * This API call is used to retrieve a wallet’s addresses. - * + * * @param int $limit The maximum number of addresses to be returned. * @param string $prevId Continue iterating (provided by nextBatchPrevId in the previous list) * @param int $sortOrder Order the addresses by creation date. -1 is newest first, 1 is for oldest first. * @return array */ - public function getWalletAddresses(string $labelContains = null, int $limit = null, bool $mine = null, string $prevId = null, array $chains = [], int $sort = null) { + public function getWalletAddresses(string $labelContains = null, int $limit = null, bool $mine = null, string $prevId = null, array $chains = [], int $sort = null) + { $this->url = $this->APIEndpoint . '/wallet/' . $this->walletId . '/addresses'; $this->params = [ 'labelContains' => $labelContains, @@ -290,12 +309,13 @@ public function getWalletAddresses(string $labelContains = null, int $limit = nu /** * This API call lists all blockchain transactions for a given wallet. - * + * * @param string $prevId Continue iterating (provided by nextBatchPrevId in the previous list result) * @param bool $allTokens Gets details of all token transactions associated with this wallet. Only valid for ETH/TETH. * @return array */ - public function getWalletTransactions(string $prevId = null, bool $allTokens = false) { + public function getWalletTransactions(string $prevId = null, bool $allTokens = false) + { $this->url = $this->APIEndpoint . '/wallet/' . $this->walletId . '/tx'; $this->params = [ 'prevId' => $prevId, @@ -306,18 +326,19 @@ public function getWalletTransactions(string $prevId = null, bool $allTokens = f /** * This API call retrieves object information for a specific transaction hash by specifying the transaction ID. - * + * * @param string $transactionId Transaction hash to retrieve. * @return array */ - public function getWalletTransaction(string $transactionId) { + public function getWalletTransaction(string $transactionId) + { $this->url = $this->APIEndpoint . '/wallet/' . $this->walletId . '/tx/' . $transactionId; return $this->__execute('GET'); } /** * This API call will retrieve the unspent transaction outputs (UTXOs) within a wallet. - * + * * @param string $prevId Continue iterating wallets from this prevId as provided by nextBatchPrevId in the previous list * @param int $minValue Ignore unspents smaller than this amount of satoshis * @param int $maxValue Ignore unspents larger than this amount of satoshis @@ -325,7 +346,8 @@ public function getWalletTransaction(string $transactionId) { * @param int $minConfirms Ignores unspents that have fewer than the given confirmations * @return array */ - public function listWalletUnspents(string $prevId = null, int $minValue = null, int $maxValue = null, int $minHeight = null, int $minConfirms = null) { + public function listWalletUnspents(string $prevId = null, int $minValue = null, int $maxValue = null, int $minHeight = null, int $minConfirms = null) + { $this->url = $this->APIEndpoint . '/wallet/' . $this->walletId . '/unspents'; $this->params = [ 'prevId' => $prevId, @@ -339,17 +361,18 @@ public function listWalletUnspents(string $prevId = null, int $minValue = null, /** * This API call will calculate the total balance across all wallets with the specified coin type. - * + * * @return array */ - public function getTotalBalances() { + public function getTotalBalances() + { $this->url = $this->APIEndpoint . '/wallet/balances'; return $this->__execute('GET'); } /** * This API call will retrieve the maximum amount that can be spent with a single transaction from the wallet. - * + * * @param int $limit Max number of unspents to use (if less than 200) * @param int $minValue Ignore unspents smaller than this amount of satoshis * @param int $maxValue Ignore unspents larger than this amount of satoshis @@ -359,7 +382,8 @@ public function getTotalBalances() { * @param bool $enforceMinConfirmsForChange Apply the required confirmations set in minConfirms for change outputs * @return type */ - public function getMaximumSpendable(int $limit = null, int $minValue = null, int $maxValue = null, int $minHeight = null, int $feeRate = null, int $minConfirms = null, bool $enforceMinConfirmsForChange = null) { + public function getMaximumSpendable(int $limit = null, int $minValue = null, int $maxValue = null, int $minHeight = null, int $feeRate = null, int $minConfirms = null, bool $enforceMinConfirmsForChange = null) + { $this->url = $this->APIEndpoint . '/wallet/' . $this->walletId . '/maximumSpendable'; $this->params = [ 'limit' => $limit, @@ -375,12 +399,13 @@ public function getMaximumSpendable(int $limit = null, int $minValue = null, int /** * Prevent all spend activity on a wallet. - * + * * @param string $otp An OTP code for the account obtained using the second factor authentication device * @param int $duration Length of time in seconds to freeze spend activity. Defaults to 1 hour. * @return array */ - public function freezeWallet(string $otp, int $duration = 3600) { + public function freezeWallet(string $otp, int $duration = 3600) + { $this->url = $this->APIEndpoint . '/wallet/' . $this->walletId . '/freeze'; $this->params = [ 'otp' => $otp, @@ -391,12 +416,13 @@ public function freezeWallet(string $otp, int $duration = 3600) { /** * Retrieve a keychain based on its key id. - * + * * @param int $limit Max number of results in a single call. Defaults to 25. * @param string $prevId Continue iterating (provided by nextBatchPrevId in the previous list) * @return array */ - public function listKeychains(int $limit = 25, string $prevId = null) { + public function listKeychains(int $limit = 25, string $prevId = null) + { $this->url = $this->APIEndpoint . '/key'; $this->params = [ 'limit' => $limit, @@ -407,24 +433,26 @@ public function listKeychains(int $limit = 25, string $prevId = null) { /** * Retrieve a keychain based on its key id. - * + * * @param string $keyId The keychain’s key id. * @return array */ - public function getKeychain(string $keyId) { + public function getKeychain(string $keyId) + { $this->url = $this->APIEndpoint . '/key/' . $keyId; return $this->__execute('GET'); } /** * Creates a new keychain on BitGo’s servers and returns the public keychain to the caller. - * + * * @param string $source The origin of the keychain. Must be 'bitgo' for a BitGo key. * @param string $enterprise The enterprise id of the BitGo key (only for ETH) * @param bool $newFeeAddress Create a new keychain instead of fetching enterprise key (only for Ethereum) * @return array */ - public function createBitGoKeychain(string $source = 'bitgo', string $enterprise = null, bool $newFeeAddress = null) { + public function createBitGoKeychain(string $source = 'bitgo', string $enterprise = null, bool $newFeeAddress = null) + { $this->url = $this->APIEndpoint . '/key'; $this->params = [ 'source' => $source, @@ -436,12 +464,13 @@ public function createBitGoKeychain(string $source = 'bitgo', string $enterprise /** * Creates a new backup keychain on a third party specializing in key recovery services. - * + * * @param string $provider The backup provider for the keychain, e. g. 'cme' * @param string $source The origin of the keychain. Must be 'backup' for a backup key. * @return array */ - public function createBackupKeychain(string $provider, string $source = 'bitgo') { + public function createBackupKeychain(string $provider, string $source = 'bitgo') + { $this->url = $this->APIEndpoint . '/key'; $this->params = [ 'source' => $source, @@ -452,13 +481,14 @@ public function createBackupKeychain(string $provider, string $source = 'bitgo') /** * This API call allows you to add a public keychain on BitGo’s server. - * + * * @param string $pub The keychain’s public key. * @param string $encryptedPrv The keychain’s encrypted private key. * @param string $source The origin of the keychain, e. g. 'bitgo' or 'backup' * @return array */ - public function addKeychain(string $pub, string $encryptedPrv = null, string $source = 'bitgo') { + public function addKeychain(string $pub, string $encryptedPrv = null, string $source = 'bitgo') + { $this->url = $this->APIEndpoint . '/key'; $this->params = [ 'pub' => $pub, @@ -469,16 +499,17 @@ public function addKeychain(string $pub, string $encryptedPrv = null, string $so } /** - * Add a rule to a wallet’s policy. A wallet policy’s rules control the conditions under which BitGo will use + * Add a rule to a wallet’s policy. A wallet policy’s rules control the conditions under which BitGo will use * its single key to sign a transaction. - * + * * @param string $id The id of the policy rule * @param string $type The type of the policy. See Policy types (https://www.bitgo.com/api/v2/#policy-types) * @param string $condition The condition that triggers the policy. See Policy types (https://www.bitgo.com/api/v2/#policy-types) * @param string $action The action to take when the policy is triggered. Should be either 'deny' or 'getapproval' * @return array */ - public function setVelocityPolicyRule(string $id, string $type, string $condition, string $action) { + public function setVelocityPolicyRule(string $id, string $type, string $condition, string $action) + { $this->url = $this->APIEndpoint . '/wallet/' . $id . '/policy/rule'; $this->params = [ 'id' => $id, @@ -491,14 +522,15 @@ public function setVelocityPolicyRule(string $id, string $type, string $conditio /** * Update a rule on a wallet’s policy. - * + * * @param string $id The id of the policy rule to be updated. (This value can’t be changed) * @param string $type The type of the policy. (This value can’t be changed) * @param string $condition The new condition that triggers the policy. See Policy types (https://www.bitgo.com/api/v2/#policy-types) * @param string $action The new action to take when the policy is triggered. Should be either 'deny' or 'getapproval' * @return array */ - public function updateVelocityPolicyRule(string $id, string $type, string $condition, string $action) { + public function updateVelocityPolicyRule(string $id, string $type, string $condition, string $action) + { $this->url = $this->APIEndpoint . '/wallet/' . $id . '/policy/rule'; $this->params = [ 'id' => $id, @@ -510,16 +542,17 @@ public function updateVelocityPolicyRule(string $id, string $type, string $condi } /** - * Remove a policy rule with the specified id. This may require a secondary approval if there is more + * Remove a policy rule with the specified id. This may require a secondary approval if there is more * than 1 “admin” user on the wallet. - * + * * @param string $id The id of the policy rule to be removed. * @param string $type The type of the policy. * @param string $condition The condition that triggers the policy. * @param string $action The action to take when the policy is triggered. * @return array */ - public function removePolicyRule(string $id, string $type, string $condition, string $action) { + public function removePolicyRule(string $id, string $type, string $condition, string $action) + { $this->url = $this->APIEndpoint . '/wallet/' . $id . '/policy/rule'; $this->params = [ 'id' => $id, @@ -532,44 +565,48 @@ public function removePolicyRule(string $id, string $type, string $condition, st /** * This API call is for checking incoming and outgoing wallet shares for the logged-in account. - * + * * @return array */ - public function listWalletShares() { + public function listWalletShares() + { $this->url = $this->APIEndpoint . '/walletshare'; return $this->__execute('GET'); } /** * Gets incoming and outgoing wallet shares for specific share ID. - * + * * @param string $shareId The wallet share Id * @return array */ - public function getWalletShare(string $shareId) { + public function getWalletShare(string $shareId) + { $this->url = $this->APIEndpoint . '/walletshare/' . $shareId; return $this->__execute('GET'); } /** * Resends the wallet share invitation to the share recipient. The wallet share should not have been accepted yet. - * + * * @param string $shareId The wallet share Id * @return array */ - public function resendWalletShareInvite(string $shareId) { + public function resendWalletShareInvite(string $shareId) + { $this->url = $this->APIEndpoint . '/walletshare/' . $shareId . '/resendemail'; return $this->__execute(); } /** - * Can be used to cancel a pending outgoing wallet share, or reject an incoming share. The share should not have + * Can be used to cancel a pending outgoing wallet share, or reject an incoming share. The share should not have * been accepted yet. - * + * * @param string $shareId The wallet share Id * @return array */ - public function cancelWalletShare(string $shareId) { + public function cancelWalletShare(string $shareId) + { $this->url = $this->APIEndpoint . '/walletshare/' . $shareId; $this->params = [ 'walletShareId' => $shareId @@ -579,11 +616,12 @@ public function cancelWalletShare(string $shareId) { /** * In order to revoke the share after they have accepted, you can remove the user from the wallet. - * + * * @param string $userId The user id of the user to remove (can be found on the wallet object) * @return array */ - public function removeWalletUser(string $userId) { + public function removeWalletUser(string $userId) + { $this->url = $this->APIEndpoint . '/wallet/' . $this->walletId . '/user/' . $userId; $this->params = [ 'walletId' => $this->walletId, @@ -594,24 +632,26 @@ public function removeWalletUser(string $userId) { /** * This API calls retrieves the object information for a pending approval by id. - * + * * @param string $pendingApprovalId The pending approval Id * @return array */ - public function getPendingApproval(string $pendingApprovalId) { + public function getPendingApproval(string $pendingApprovalId) + { $this->url = $this->APIEndpoint . '/pendingapprovals/' . $pendingApprovalId; return $this->__execute('GET'); } /** * List pending approvals on a wallet or an enterprise by providing either a wallet id or an enterprise in the url. - * + * * @param string $walletID Base address of the wallet * @param string $enterprise The public ID of the enterprise * @param bool $allTokens Gets details of all token pending approvals. Only valid for ETH/TETH * @return type */ - public function listPendingApprovals(string $walletID = null, string $enterprise = null, bool $allTokens = false) { + public function listPendingApprovals(string $walletID = null, string $enterprise = null, bool $allTokens = false) + { $this->url = $this->APIEndpoint . '/pendingapprovals'; $this->params = [ 'walletID' => $walletID, @@ -623,12 +663,13 @@ public function listPendingApprovals(string $walletID = null, string $enterprise /** * Get webhook payload - * + * * @param bool $decodeJson Set true to decode the JSON * @param bool $decodeAsArray Set true to decode the JSON as array * @return type */ - public static function getWebhookPayload(bool $decodeJson = true, bool $decodeAsArray = true) { + public static function getWebhookPayload(bool $decodeJson = true, bool $decodeAsArray = true) + { if ($decodeJson) { return json_decode(file_get_contents('php://input'), $decodeAsArray); } else { @@ -638,11 +679,12 @@ public static function getWebhookPayload(bool $decodeJson = true, bool $decodeAs /** * List all webhooks set up on the wallet. - * + * * @param bool $allTokens Gets details of all token pending approvals. Only valid for ETH/TETH * @return array */ - public function listWalletWebhooks(bool $allTokens = false) { + public function listWalletWebhooks(bool $allTokens = false) + { $this->url = $this->APIEndpoint . '/wallet/' . $this->walletId . '/webhooks'; $this->params = [ 'allTokens' => $this->coin === CurrencyCode::ETHEREUM || $this->coin === CurrencyCode::ETHEREUM_TESTNET ? $allTokens : null @@ -652,13 +694,14 @@ public function listWalletWebhooks(bool $allTokens = false) { /** * Add a webhook that will result in an HTTP callback at the specified URL from BitGo when events are triggered. - * + * * @param string $url URL to fire the webhook to. * @param string $type Type of event to listen to (can be 'transfer' or 'pendingaapproval'). * @param int $numConfirmations Number of confirmations before triggering the webhook. If 0 or unspecified, requests will be sent to the callback endpoint when the transfer is first seen and when it is confirmed. * @return array */ - public function addWalletWebhook(string $url, string $type, int $numConfirmations = null) { + public function addWalletWebhook(string $url, string $type, int $numConfirmations = null) + { $this->url = $this->APIEndpoint . '/wallet/' . $this->walletId . '/webhooks'; $this->params = [ 'url' => $url, @@ -670,12 +713,13 @@ public function addWalletWebhook(string $url, string $type, int $numConfirmation /** * Removing a webhook will cause new events of the specified type to no longer trigger HTTP callbacks to your URLs. - * + * * @param string $url URL for callback requests to be made at. * @param string $type Type of event to listen to (can be 'transfer' or 'pendingaapproval'). * @return array */ - public function removeWalletWebhook(string $url, string $type) { + public function removeWalletWebhook(string $url, string $type) + { $this->url = $this->APIEndpoint . '/wallet/' . $this->walletId . '/webhooks'; $this->params = [ 'url' => $url, @@ -686,13 +730,14 @@ public function removeWalletWebhook(string $url, string $type) { /** * This API allows you to simulate and test a webhook so you can view its response. - * + * * @param string $webhookId Webhook ID. * @param string $transferId ID of the transfer to be used in the simulation. * @param string $pendingApprovalId ID of the pending approval to be used in the simulation. * @return array */ - public function simulateWalletWebhook(string $webhookId, string $transferId = null, string $pendingApprovalId = null) { + public function simulateWalletWebhook(string $webhookId, string $transferId = null, string $pendingApprovalId = null) + { $this->url = $this->APIEndpoint . '/wallet/' . $this->walletId . '/webhooks/' . $webhookId . '/simulate'; $this->params = [ 'webhookId' => $webhookId, @@ -704,24 +749,26 @@ public function simulateWalletWebhook(string $webhookId, string $transferId = nu /** * List all webhooks set up on the user. - * + * * @return array */ - public function listUserWebhooks() { + public function listUserWebhooks() + { $this->url = $this->APIEndpoint . '/webhooks'; return $this->__execute('GET'); } /** * Add a webhook that will result in an HTTP callback at the specified URL from BitGo when events are triggered. - * + * * @param string $url URL to fire the webhook to. * @param string $type Type of event to listen to (can be of type 'block'). * @param string $label Label of the new webhook. * @param int $numConfirmations Number of confirmations before triggering the webhook. * @return array */ - public function addUserWebhook(string $url, string $type, string $label = null, int $numConfirmations = null) { + public function addUserWebhook(string $url, string $type, string $label = null, int $numConfirmations = null) + { $this->url = $this->APIEndpoint . '/webhooks'; $this->params = [ 'url' => $url, @@ -734,12 +781,13 @@ public function addUserWebhook(string $url, string $type, string $label = null, /** * Removing a webhook will cause new events of the specified type to no longer trigger HTTP callbacks to your URLs. - * + * * @param string $url URL for callback requests to be made at. * @param string $type Type of event to listen to (can be of type 'block'). * @return array */ - public function removeUserWebhook(string $url, string $type) { + public function removeUserWebhook(string $url, string $type) + { $this->url = $this->APIEndpoint . '/webhooks'; $this->params = [ 'url' => $url, @@ -750,11 +798,12 @@ public function removeUserWebhook(string $url, string $type) { /** * This API allows you to simulate and test a webhook so you can view its response. - * + * * @param string $webhookId * @return array */ - public function simulateUserWebhook(string $webhookId, string $blockId = null) { + public function simulateUserWebhook(string $webhookId, string $blockId = null) + { $this->url = $this->APIEndpoint . '/webhooks/' . $webhookId . '/simulate'; $this->params = [ 'webhookId' => $webhookId, @@ -765,7 +814,7 @@ public function simulateUserWebhook(string $webhookId, string $blockId = null) { /** * Adds a webhook that will result in an HTTP callback at the specified URL from BitGo when events are triggered. - * + * * @param string $url URL to fire the webhook to. * @param string $type Type of event to listen to (can be 'block' or 'wallet_confirmation'). * @param string $label Label of the new webhook. @@ -773,7 +822,8 @@ public function simulateUserWebhook(string $webhookId, string $blockId = null) { * @return array */ - public function addBlockWebhook(string $url, string $type = 'block', string $label = null, int $numConfirmations = null) { + public function addBlockWebhook(string $url, string $type = 'block', string $label = null, int $numConfirmations = null) + { $this->url = $this->APIEndpoint . '/webhooks'; $this->params = [ 'url' => $url, @@ -786,22 +836,24 @@ public function addBlockWebhook(string $url, string $type = 'block', string $lab /** * Returns block webhooks. The types of webhooks are block and wallet_confirmation notifications. - * + * * @return array */ - public function listBlockWebhooks() { + public function listBlockWebhooks() + { $this->url = $this->APIEndpoint . '/webhooks'; return $this->__execute('GET'); } /** * Removing a webhook will cause new events of the specified type to no longer trigger HTTP callbacks to your URLs. - * + * * @param string $url * @param string $type * @return array */ - public function removeBlockWebhook(string $url, string $type = 'block') { + public function removeBlockWebhook(string $url, string $type = 'block') + { $this->url = $this->APIEndpoint . '/webhooks'; $this->params = [ 'url' => $url, @@ -812,21 +864,23 @@ public function removeBlockWebhook(string $url, string $type = 'block') { /** * This API is still being developed. BitGo will update this section soon. - * + * * @return array */ - public function getMarketPriceData() { + public function getMarketPriceData() + { $this->url = $this->APIEndpoint . '/market/latest'; return $this->__execute('GET'); } /** * Returns the recommended fee rate per kilobyte to confirm a transaction within a target number of blocks. - * + * * @param int $numBlocks The target number of blocks for the transaction to be confirmed. The accepted range is 1 - 1000 and the default value is 2. * @return array */ - public function estimateTransactionFees(int $numBlocks = null) { + public function estimateTransactionFees(int $numBlocks = null) + { $this->url = $this->APIEndpoint . '/tx/fee'; $this->params = [ 'numBlocks' => $numBlocks @@ -834,7 +888,8 @@ public function estimateTransactionFees(int $numBlocks = null) { return $this->__execute('GET'); } - private function __execute(string $requestType = 'POST') { + private function __execute(string $requestType = 'POST') + { $ch = curl_init($this->url); if ($requestType === 'GET') { curl_setopt($ch, CURLOPT_URL, $this->url . '?' . http_build_query(array_filter($this->params))); diff --git a/src/Enum/AddressType.php b/src/Enum/AddressType.php index 5b801c6..33dfe0e 100644 --- a/src/Enum/AddressType.php +++ b/src/Enum/AddressType.php @@ -3,9 +3,9 @@ /** * ____ _ _ ____ ____ ____ _ __ * | __ )(_) |_ / ___| ___/ ___|| _ \| |/ / - * | _ \| | __| | _ / _ \___ \| | | | ' / - * | |_) | | |_| |_| | (_) |__) | |_| | . \ - * |____/|_|\__|\____|\___/____/|____/|_|\_\ + * | _ \| | __| | _ / _ \___ \| | | | ' / + * | |_) | | |_| |_| | (_) |__) | |_| | . \ + * |____/|_|\__|\____|\___/____/|____/|_|\_\ * * @package BitGoSDK PHP * @author Neto Melo @@ -15,18 +15,18 @@ namespace neto737\BitGoSDK\Enum; -abstract class AddressType { - +abstract class AddressType +{ const LEGACY_DEPOSIT = 0; const LEGACY_CHANGE = 1; - + const P2SH_DEPOSIT = 10; const P2SH_CHANGE = 11; - + const BECH32_DEPOSIT = 20; const BECH32_CHANGE = 21; // Taproot fork address format const BECH32M_DEPOSIT = 30; const BECH32M_CHANGE = 31; -} \ No newline at end of file +} diff --git a/src/Enum/CurrencyCode.php b/src/Enum/CurrencyCode.php index 31a9fa2..3970a20 100644 --- a/src/Enum/CurrencyCode.php +++ b/src/Enum/CurrencyCode.php @@ -3,9 +3,9 @@ /** * ____ _ _ ____ ____ ____ _ __ * | __ )(_) |_ / ___| ___/ ___|| _ \| |/ / - * | _ \| | __| | _ / _ \___ \| | | | ' / - * | |_) | | |_| |_| | (_) |__) | |_| | . \ - * |____/|_|\__|\____|\___/____/|____/|_|\_\ + * | _ \| | __| | _ / _ \___ \| | | | ' / + * | |_) | | |_| |_| | (_) |__) | |_| | . \ + * |____/|_|\__|\____|\___/____/|____/|_|\_\ * * @package BitGoSDK PHP * @author Neto Melo @@ -15,8 +15,8 @@ namespace neto737\BitGoSDK\Enum; -abstract class CurrencyCode { - +abstract class CurrencyCode +{ // Mainnet const ALGORAND = 'algo'; const AVAX = 'avax'; @@ -57,7 +57,7 @@ abstract class CurrencyCode { const TRON_TESTNET = 'ttrx'; const RIPPLE_TESTNET = 'txrp'; const ZCASH_TESTNET = 'tzec'; - + //ERC20 TOKENS const ERC = 'erc'; //BitGo’s sample ERC20 token const OMISE_GO = 'omg'; diff --git a/tests/SmokeTest.php b/tests/SmokeTest.php new file mode 100644 index 0000000..6b503e2 --- /dev/null +++ b/tests/SmokeTest.php @@ -0,0 +1,33 @@ + Date: Sun, 18 Oct 2026 17:50:44 +1030 Subject: [PATCH 2/3] Updates --- CHANGELOG.md | 3 +++ CONTRIBUTING.md | 10 +++++----- README.md | 2 +- composer.json | 23 ++++++++++++++++++++++- 4 files changed, 31 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9a12863..c8cf713 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,9 +14,12 @@ Entries for 2.2.3 and earlier were reconstructed from the git history in October - `.editorconfig` and `.gitattributes`. - Dev tooling: PHPUnit 9.6, PHPStan (level 6, with a baseline for the existing code) and PHP-CS-Fixer (PSR-12). - A GitHub Actions CI workflow: `php -l` and PHPUnit on PHP 7.4 to 8.5 with lowest and highest dependencies, plus PHPStan and a coding-standard check. +- Composer scripts: `composer test`, `composer analyse`, `composer cs` and `composer cs:fix`. +- `homepage` and `support` (issues, source, security policy) in `composer.json`. ### Changed +- **The minimum PHP version is now 7.4** (was 7.0). - The project is now licensed under MIT. 2.2.3 and earlier were released under GPL-3.0. - `src/` and `examples/` were reformatted to PSR-12. This is whitespace and brace placement only, with no behaviour change. - Composer dist archives no longer include `tests/`, `examples/`, `docs/` or dotfiles. The examples are still available in the repository. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b57cfcb..18bf519 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -40,7 +40,7 @@ If a fix applies to both lines, open the pull request against `2.x`. A maintaine You need: -- PHP 7.0 or newer with the `curl` and `bcmath` extensions. A current PHP 8.x is recommended so you see deprecation notices. 2.3.0 raises the minimum to 7.4. +- PHP 7.4 or newer with the `curl` and `bcmath` extensions. A current PHP 8.x is recommended so you see deprecation notices. - [Composer](https://getcomposer.org/). - A [BitGo testnet](https://app.bitgo-test.com/) account and access token, if you want to run requests against the API. Never use production tokens or real funds while developing. @@ -55,7 +55,7 @@ composer install ## Coding style - Follow the style of the surrounding code: 4-space indentation, LF line endings, UTF-8 and a final newline. [.editorconfig](.editorconfig) sets these up for most editors. -- Code must follow [PSR-12](https://www.php-fig.org/psr/psr-12/). CI enforces it with PHP-CS-Fixer. Run `vendor/bin/php-cs-fixer fix` before you push. +- Code must follow [PSR-12](https://www.php-fig.org/psr/psr-12/). CI enforces it with PHP-CS-Fixer. Run `composer cs:fix` before you push. - 2.x changes must not break the public API. Don't rename or remove public methods or reorder their parameters. Widening a type (for example `int` to `int|string`) is fine. Breaking changes go to 3.x. - Code must still run on the minimum PHP version in `composer.json`. Don't use syntax or functions newer than that. - Give every public method a docblock with a short description, `@param` lines and `@return`, like the existing methods. @@ -67,9 +67,9 @@ CI runs these checks on every pull request. PHPUnit and `php -l` run on PHP 7.4 1. Run the same checks locally: ```sh - vendor/bin/phpunit - vendor/bin/phpstan analyse - vendor/bin/php-cs-fixer fix --dry-run --diff + composer test + composer analyse + composer cs ``` PHPStan runs at level 6 against a baseline (`phpstan-baseline.neon`) of the errors in the existing code. Don't add new entries to it. When a fix removes an error, regenerate the baseline with `vendor/bin/phpstan analyse --generate-baseline phpstan-baseline.neon`. diff --git a/README.md b/README.md index eacdaac..b568a84 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ BitGoSDK written in PHP. This SDK contains methods for easily interacting with t ## Requirements -- PHP 7.0 or earlier with: +- PHP 7.4 or newer with: - cURL - BCMath diff --git a/composer.json b/composer.json index edb23d5..84505ca 100644 --- a/composer.json +++ b/composer.json @@ -3,6 +3,7 @@ "description": "A BitGo SDK written in PHP", "type": "library", "keywords": ["bitgo", "sdk", "bitcoin"], + "homepage": "https://github.com/neto737/BitGoSDK-PHP", "license": "MIT", "authors": [ @@ -12,6 +13,12 @@ } ], + "support": { + "issues": "https://github.com/neto737/BitGoSDK-PHP/issues", + "source": "https://github.com/neto737/BitGoSDK-PHP", + "security": "https://github.com/neto737/BitGoSDK-PHP/security/policy" + }, + "autoload": { "psr-4": { "neto737\\BitGoSDK\\": "src/" @@ -25,7 +32,7 @@ }, "require": { - "php": ">=7.0", + "php": ">=7.4", "ext-curl": "*", "ext-bcmath": "*" }, @@ -36,6 +43,20 @@ "phpunit/phpunit": "^9.6.33" }, + "scripts": { + "test": "phpunit", + "analyse": "phpstan analyse", + "cs": "php-cs-fixer fix --dry-run --diff", + "cs:fix": "php-cs-fixer fix" + }, + + "scripts-descriptions": { + "test": "Run the PHPUnit test suite.", + "analyse": "Run PHPStan static analysis.", + "cs": "Check the coding standard without changing files.", + "cs:fix": "Fix coding standard violations." + }, + "config": { "sort-packages": true } From cd4c88c4d93ae941d3ab0c2efab55ae3a79003b1 Mon Sep 17 00:00:00 2001 From: Neto Date: Sun, 18 Oct 2026 17:56:49 +1030 Subject: [PATCH 3/3] Bugfixes --- src/BitGoExpress.php | 26 +++++++++++++------------- src/BitGoSDK.php | 38 +++++++++++++++++++------------------- 2 files changed, 32 insertions(+), 32 deletions(-) diff --git a/src/BitGoExpress.php b/src/BitGoExpress.php index 9e840c6..7b071d3 100644 --- a/src/BitGoExpress.php +++ b/src/BitGoExpress.php @@ -54,7 +54,7 @@ public function __construct(string $hostname, int $port, string $coin = Currency * @param bool $extensible True if the session is supposed to be extensible beyond a one-hour duration. * @return array */ - public function login(string $email, string $password, string $otp, bool $extensible = null) + public function login(string $email, string $password, string $otp, ?bool $extensible = null) { $this->url = $this->AuthAPIEndpoint . '/user/login'; $this->params = [ @@ -92,7 +92,7 @@ public function ping() * @param string $passcodeEncryptionCode Encryption code for wallet passphrase (used for lost passphrase recovery) * @return array */ - public function generateWallet(string $label, string $passphrase, string $userKey = null, string $backupXpub = null, string $backupXpubProvider = null, string $enterprise = null, bool $disableTransactionNotifications = null, int $gasPrice = null, string $passcodeEncryptionCode = null) + public function generateWallet(string $label, string $passphrase, ?string $userKey = null, ?string $backupXpub = null, ?string $backupXpubProvider = null, ?string $enterprise = null, ?bool $disableTransactionNotifications = null, ?int $gasPrice = null, ?string $passcodeEncryptionCode = null) { $this->url = $this->APIEndpoint . '/wallet/generate'; $this->params = [ @@ -122,7 +122,7 @@ public function generateWallet(string $label, string $passphrase, string $userKe * @param bool $disableTransactionNotifications Will prevent wallet transaction notifications if set to true. * @return array */ - public function addWallet(string $label, int $m, int $n, array $keys, string $enterprise = null, bool $isCold = null, bool $disableTransactionNotifications = null) + public function addWallet(string $label, int $m, int $n, array $keys, ?string $enterprise = null, ?bool $isCold = null, ?bool $disableTransactionNotifications = null) { $this->url = $this->APIEndpoint . '/wallet'; $this->params = [ @@ -162,7 +162,7 @@ public function addWallet(string $label, int $m, int $n, array $keys, string $en * @param string $ledgerSequenceDelta Relative ledger height (in relation to the current ledger) that the transaction should be accepted in, whereafter it will be rejected. * @return array */ - public function sendTransaction(string $address, int $amount, string $walletPassphrase, string $prv = null, int $numBlocks = null, int $feeRate = null, string $comment = null, array $unspents = null, int $minConfirms = null, bool $enforceMinConfirmsForChange = null, int $targetWalletUnspents = null, bool $noSplitChange = null, int $minValue = null, int $maxValue = null, int $gasPrice = null, int $gasLimit = null, int $sequenceId = null, bool $segwit = null, int $lastLedgerSequence = null, string $ledgerSequenceDelta = null) + public function sendTransaction(string $address, int $amount, string $walletPassphrase, ?string $prv = null, ?int $numBlocks = null, ?int $feeRate = null, ?string $comment = null, ?array $unspents = null, ?int $minConfirms = null, ?bool $enforceMinConfirmsForChange = null, ?int $targetWalletUnspents = null, ?bool $noSplitChange = null, ?int $minValue = null, ?int $maxValue = null, ?int $gasPrice = null, ?int $gasLimit = null, ?int $sequenceId = null, ?bool $segwit = null, ?int $lastLedgerSequence = null, ?string $ledgerSequenceDelta = null) { $this->url = $this->APIEndpoint . '/wallet/' . $this->walletId . '/sendcoins'; $this->params = [ @@ -215,7 +215,7 @@ public function sendTransaction(string $address, int $amount, string $walletPass * @param string $ledgerSequenceDelta Relative ledger height (in relation to the current ledger) that the transaction should be accepted in, whereafter it will be rejected. * @return array */ - public function sendTransactionToMany(array $recipients, string $walletPassphrase, string $prv = null, int $numBlocks = null, int $feeRate = null, string $comment = null, array $unspents = null, int $minConfirms = null, bool $enforceMinConfirmsForChange = null, int $targetWalletUnspents = null, bool $noSplitChange = null, int $minValue = null, int $maxValue = null, int $gasPrice = null, int $gasLimit = null, int $sequenceId = null, bool $segwit = null, int $lastLedgerSequence = null, string $ledgerSequenceDelta = null) + public function sendTransactionToMany(array $recipients, string $walletPassphrase, ?string $prv = null, ?int $numBlocks = null, ?int $feeRate = null, ?string $comment = null, ?array $unspents = null, ?int $minConfirms = null, ?bool $enforceMinConfirmsForChange = null, ?int $targetWalletUnspents = null, ?bool $noSplitChange = null, ?int $minValue = null, ?int $maxValue = null, ?int $gasPrice = null, ?int $gasLimit = null, ?int $sequenceId = null, ?bool $segwit = null, ?int $lastLedgerSequence = null, ?string $ledgerSequenceDelta = null) { $this->url = $this->APIEndpoint . '/wallet/' . $this->walletId . '/sendmany'; $this->params = [ @@ -258,7 +258,7 @@ public function sendTransactionToMany(array $recipients, string $walletPassphras * @param bool $enforceMinConfirmsForChange Apply the required confirmations set in minConfirms for change outputs * @return array */ - public function consolidateWalletUnspents(string $walletPassphrase, int $numUnspentsToMake = null, int $limit = null, int $minValue = null, int $maxValue = null, int $minHeight = null, int $feeRate = null, int $feeTxConfirmTarget = null, int $maxFeePercentage = null, int $minConfirms = null, bool $enforceMinConfirmsForChange = null) + public function consolidateWalletUnspents(string $walletPassphrase, ?int $numUnspentsToMake = null, ?int $limit = null, ?int $minValue = null, ?int $maxValue = null, ?int $minHeight = null, ?int $feeRate = null, ?int $feeTxConfirmTarget = null, ?int $maxFeePercentage = null, ?int $minConfirms = null, ?bool $enforceMinConfirmsForChange = null) { $this->url = $this->APIEndpoint . '/wallet/' . $this->walletId . '/consolidateunspents'; $this->params = [ @@ -294,7 +294,7 @@ public function consolidateWalletUnspents(string $walletPassphrase, int $numUnsp * @param int $feeTxConfirmTarget Fee rate is automatically chosen by targeting a transaction confirmation in this number of blocks (Only available on BTC, feeRate takes precedence if also set) * @return array */ - public function funoutWalletUnspents(string $walletPassphrase, string $xprv = null, int $maxNumInputsToUse = null, int $numUnspentsToMake = null, int $minValue = null, int $maxValue = null, int $minHeight = null, int $maxFeePercentage = null, int $minConfirms = null, bool $enforceMinConfirmsForChange = null, int $feeRate = null, int $feeTxConfirmTarget = null) + public function funoutWalletUnspents(string $walletPassphrase, ?string $xprv = null, ?int $maxNumInputsToUse = null, ?int $numUnspentsToMake = null, ?int $minValue = null, ?int $maxValue = null, ?int $minHeight = null, ?int $maxFeePercentage = null, ?int $minConfirms = null, ?bool $enforceMinConfirmsForChange = null, ?int $feeRate = null, ?int $feeTxConfirmTarget = null) { $this->url = $this->APIEndpoint . '/wallet/' . $this->walletId . '/fanoutunspents'; $this->params = [ @@ -329,7 +329,7 @@ public function funoutWalletUnspents(string $walletPassphrase, string $xprv = nu * @param string $ledgerSequenceDelta Relative ledger height (in relation to the current ledger) that the transaction should be accepted in, whereafter it will be rejected. * @return array */ - public function sweep(string $address, string $walletPassphrase, string $xprv = null, string $otp = null, int $feeRate = null, int $feeTxConfirmTarget = null, int $gasPrice = null, int $sequenceId = null, int $lastLedgerSequence = null, string $ledgerSequenceDelta = null) + public function sweep(string $address, string $walletPassphrase, ?string $xprv = null, ?string $otp = null, ?int $feeRate = null, ?int $feeTxConfirmTarget = null, ?int $gasPrice = null, ?int $sequenceId = null, ?int $lastLedgerSequence = null, ?string $ledgerSequenceDelta = null) { $this->url = $this->APIEndpoint . '/wallet/' . $this->walletId . '/sweep'; $this->params = [ @@ -365,7 +365,7 @@ public function sweep(string $address, string $walletPassphrase, string $xprv = * @param string $ledgerSequenceDelta Relative ledger height (in relation to the current ledger) that the transaction should be accepted in, whereafter it will be rejected. * @return object Returns the newly created transaction description object. */ - public function buildTransaction(array $recipients, int $numBlocks = null, int $feeRate = null, int $minConfirms = null, bool $enforceMinConfirmsForChange = null, array $unspents = null, int $targetWalletUnspents = null, bool $noSplitChange = null, int $minValue = null, int $maxValue = null, int $gasPrice = null, int $lastLedgerSequence = null, string $ledgerSequenceDelta = null) + public function buildTransaction(array $recipients, ?int $numBlocks = null, ?int $feeRate = null, ?int $minConfirms = null, ?bool $enforceMinConfirmsForChange = null, ?array $unspents = null, ?int $targetWalletUnspents = null, ?bool $noSplitChange = null, ?int $minValue = null, ?int $maxValue = null, ?int $gasPrice = null, ?int $lastLedgerSequence = null, ?string $ledgerSequenceDelta = null) { $this->url = $this->APIEndpoint . '/wallet/' . $this->walletId . '/tx/build'; $this->params = [ @@ -397,7 +397,7 @@ public function buildTransaction(array $recipients, int $numBlocks = null, int $ * @param string $walletPassphrase Passphrase to decrypt the user keychain * @return object The half-signed, serialized transaction hex */ - public function signBuildTransaction($txPrebuild, string $prv = null, string $coldDerivationSeed = null, $keychain = null, string $walletPassphrase = null) + public function signBuildTransaction($txPrebuild, ?string $prv = null, ?string $coldDerivationSeed = null, $keychain = null, ?string $walletPassphrase = null) { $this->url = $this->APIEndpoint . '/wallet/' . $this->walletId . '/signtx'; $this->params = [ @@ -419,7 +419,7 @@ public function signBuildTransaction($txPrebuild, string $prv = null, string $co * @param string $comment Any additional comment to attach to the transaaction * @return array */ - public function sendBuildTransaction($halfSigned, string $otp, string $txHex = null, string $comment = null) + public function sendBuildTransaction($halfSigned, string $otp, ?string $txHex = null, ?string $comment = null) { $this->url = $this->APIEndpoint . '/wallet/' . $this->walletId . '/tx/send'; $this->params = [ @@ -452,7 +452,7 @@ public function createKeychain() * @param bool $disableEmail Set to true to prevent a notification email sent to the user added * @return array */ - public function shareWallet(string $email, string $permissions, string $walletPassphrase = null, bool $skipKeychain = null, bool $disableEmail = null) + public function shareWallet(string $email, string $permissions, ?string $walletPassphrase = null, ?bool $skipKeychain = null, ?bool $disableEmail = null) { $this->url = $this->APIEndpoint . '/wallet/' . $this->walletId . '/share'; $this->params = [ @@ -474,7 +474,7 @@ public function shareWallet(string $email, string $permissions, string $walletPa * @param string $overrideEncryptedPrv Set to an alternate encrypted prv if you wish to store an encrypted prv received out-of-band * @return array */ - public function acceptWalletShare(string $walletShareId, string $newWalletPassphrase = null, string $userPassword = null, string $overrideEncryptedPrv = null) + public function acceptWalletShare(string $walletShareId, ?string $newWalletPassphrase = null, ?string $userPassword = null, ?string $overrideEncryptedPrv = null) { $this->url = $this->APIEndpoint . '/walletshare/' . $walletShareId . '/acceptshare'; $this->params = [ diff --git a/src/BitGoSDK.php b/src/BitGoSDK.php index 3e457de..6b9723e 100644 --- a/src/BitGoSDK.php +++ b/src/BitGoSDK.php @@ -150,7 +150,7 @@ public function logout() * @param bool $allTokens Gets details of all tokens associated with this wallet. Only valid for ETH/TETH * @return array */ - public function listWallets(int $limit = 25, string $prevId = null, bool $allTokens = false) + public function listWallets(int $limit = 25, ?string $prevId = null, bool $allTokens = false) { $this->url = $this->APIEndpoint . '/wallet'; $this->params = [ @@ -195,7 +195,7 @@ public function getWalletByAddress(string $walletAddress) * @param bool $allTokens Gets transfers of all tokens associated with this wallet. Only valid for ETH/TETH. * @return array */ - public function listWalletTransfers(string $prevId = null, bool $allTokens = false) + public function listWalletTransfers(?string $prevId = null, bool $allTokens = false) { $this->url = $this->APIEndpoint . '/wallet/' . $this->walletId . '/transfer'; $this->params = [ @@ -239,7 +239,7 @@ public function getWalletTransferBySequenceId(string $sequenceId) * @param bool $lowPriority Whether the deployment of the address forwarder contract should use a low priority fee key (ETH only) * @return array */ - public function createWalletAddress(int $chain = AddressType::P2SH_DEPOSIT, string $label = null, bool $lowPriority = false, int $gasPrice = null) + public function createWalletAddress(int $chain = AddressType::P2SH_DEPOSIT, ?string $label = null, bool $lowPriority = false, ?int $gasPrice = null) { $this->url = $this->APIEndpoint . '/wallet/' . $this->walletId . '/address'; $this->params = [ @@ -257,7 +257,7 @@ public function createWalletAddress(int $chain = AddressType::P2SH_DEPOSIT, stri * @param string $addressOrId Valid address or address id of the wallet. * @return array */ - public function getWalletAddress(string $addressOrId, string $dt = null, string $memoId = null) + public function getWalletAddress(string $addressOrId, ?string $dt = null, ?string $memoId = null) { $this->url = $this->APIEndpoint . '/wallet/' . $this->walletId . '/address/' . $addressOrId; $this->params = [ @@ -274,7 +274,7 @@ public function getWalletAddress(string $addressOrId, string $dt = null, string * @param string $label Human-readable name for the address * @return array */ - public function updateWalletAddress(string $addressOrId, string $dt = null, string $memoId = null, string $label = null) + public function updateWalletAddress(string $addressOrId, ?string $dt = null, ?string $memoId = null, ?string $label = null) { $this->url = $this->APIEndpoint . '/wallet/' . $this->walletId . '/address/' . $addressOrId; $this->params = [ @@ -293,7 +293,7 @@ public function updateWalletAddress(string $addressOrId, string $dt = null, stri * @param int $sortOrder Order the addresses by creation date. -1 is newest first, 1 is for oldest first. * @return array */ - public function getWalletAddresses(string $labelContains = null, int $limit = null, bool $mine = null, string $prevId = null, array $chains = [], int $sort = null) + public function getWalletAddresses(?string $labelContains = null, ?int $limit = null, ?bool $mine = null, ?string $prevId = null, array $chains = [], ?int $sort = null) { $this->url = $this->APIEndpoint . '/wallet/' . $this->walletId . '/addresses'; $this->params = [ @@ -314,7 +314,7 @@ public function getWalletAddresses(string $labelContains = null, int $limit = nu * @param bool $allTokens Gets details of all token transactions associated with this wallet. Only valid for ETH/TETH. * @return array */ - public function getWalletTransactions(string $prevId = null, bool $allTokens = false) + public function getWalletTransactions(?string $prevId = null, bool $allTokens = false) { $this->url = $this->APIEndpoint . '/wallet/' . $this->walletId . '/tx'; $this->params = [ @@ -346,7 +346,7 @@ public function getWalletTransaction(string $transactionId) * @param int $minConfirms Ignores unspents that have fewer than the given confirmations * @return array */ - public function listWalletUnspents(string $prevId = null, int $minValue = null, int $maxValue = null, int $minHeight = null, int $minConfirms = null) + public function listWalletUnspents(?string $prevId = null, ?int $minValue = null, ?int $maxValue = null, ?int $minHeight = null, ?int $minConfirms = null) { $this->url = $this->APIEndpoint . '/wallet/' . $this->walletId . '/unspents'; $this->params = [ @@ -382,7 +382,7 @@ public function getTotalBalances() * @param bool $enforceMinConfirmsForChange Apply the required confirmations set in minConfirms for change outputs * @return type */ - public function getMaximumSpendable(int $limit = null, int $minValue = null, int $maxValue = null, int $minHeight = null, int $feeRate = null, int $minConfirms = null, bool $enforceMinConfirmsForChange = null) + public function getMaximumSpendable(?int $limit = null, ?int $minValue = null, ?int $maxValue = null, ?int $minHeight = null, ?int $feeRate = null, ?int $minConfirms = null, ?bool $enforceMinConfirmsForChange = null) { $this->url = $this->APIEndpoint . '/wallet/' . $this->walletId . '/maximumSpendable'; $this->params = [ @@ -421,7 +421,7 @@ public function freezeWallet(string $otp, int $duration = 3600) * @param string $prevId Continue iterating (provided by nextBatchPrevId in the previous list) * @return array */ - public function listKeychains(int $limit = 25, string $prevId = null) + public function listKeychains(int $limit = 25, ?string $prevId = null) { $this->url = $this->APIEndpoint . '/key'; $this->params = [ @@ -451,7 +451,7 @@ public function getKeychain(string $keyId) * @param bool $newFeeAddress Create a new keychain instead of fetching enterprise key (only for Ethereum) * @return array */ - public function createBitGoKeychain(string $source = 'bitgo', string $enterprise = null, bool $newFeeAddress = null) + public function createBitGoKeychain(string $source = 'bitgo', ?string $enterprise = null, ?bool $newFeeAddress = null) { $this->url = $this->APIEndpoint . '/key'; $this->params = [ @@ -487,7 +487,7 @@ public function createBackupKeychain(string $provider, string $source = 'bitgo') * @param string $source The origin of the keychain, e. g. 'bitgo' or 'backup' * @return array */ - public function addKeychain(string $pub, string $encryptedPrv = null, string $source = 'bitgo') + public function addKeychain(string $pub, ?string $encryptedPrv = null, string $source = 'bitgo') { $this->url = $this->APIEndpoint . '/key'; $this->params = [ @@ -650,7 +650,7 @@ public function getPendingApproval(string $pendingApprovalId) * @param bool $allTokens Gets details of all token pending approvals. Only valid for ETH/TETH * @return type */ - public function listPendingApprovals(string $walletID = null, string $enterprise = null, bool $allTokens = false) + public function listPendingApprovals(?string $walletID = null, ?string $enterprise = null, bool $allTokens = false) { $this->url = $this->APIEndpoint . '/pendingapprovals'; $this->params = [ @@ -700,7 +700,7 @@ public function listWalletWebhooks(bool $allTokens = false) * @param int $numConfirmations Number of confirmations before triggering the webhook. If 0 or unspecified, requests will be sent to the callback endpoint when the transfer is first seen and when it is confirmed. * @return array */ - public function addWalletWebhook(string $url, string $type, int $numConfirmations = null) + public function addWalletWebhook(string $url, string $type, ?int $numConfirmations = null) { $this->url = $this->APIEndpoint . '/wallet/' . $this->walletId . '/webhooks'; $this->params = [ @@ -736,7 +736,7 @@ public function removeWalletWebhook(string $url, string $type) * @param string $pendingApprovalId ID of the pending approval to be used in the simulation. * @return array */ - public function simulateWalletWebhook(string $webhookId, string $transferId = null, string $pendingApprovalId = null) + public function simulateWalletWebhook(string $webhookId, ?string $transferId = null, ?string $pendingApprovalId = null) { $this->url = $this->APIEndpoint . '/wallet/' . $this->walletId . '/webhooks/' . $webhookId . '/simulate'; $this->params = [ @@ -767,7 +767,7 @@ public function listUserWebhooks() * @param int $numConfirmations Number of confirmations before triggering the webhook. * @return array */ - public function addUserWebhook(string $url, string $type, string $label = null, int $numConfirmations = null) + public function addUserWebhook(string $url, string $type, ?string $label = null, ?int $numConfirmations = null) { $this->url = $this->APIEndpoint . '/webhooks'; $this->params = [ @@ -802,7 +802,7 @@ public function removeUserWebhook(string $url, string $type) * @param string $webhookId * @return array */ - public function simulateUserWebhook(string $webhookId, string $blockId = null) + public function simulateUserWebhook(string $webhookId, ?string $blockId = null) { $this->url = $this->APIEndpoint . '/webhooks/' . $webhookId . '/simulate'; $this->params = [ @@ -822,7 +822,7 @@ public function simulateUserWebhook(string $webhookId, string $blockId = null) * @return array */ - public function addBlockWebhook(string $url, string $type = 'block', string $label = null, int $numConfirmations = null) + public function addBlockWebhook(string $url, string $type = 'block', ?string $label = null, ?int $numConfirmations = null) { $this->url = $this->APIEndpoint . '/webhooks'; $this->params = [ @@ -879,7 +879,7 @@ public function getMarketPriceData() * @param int $numBlocks The target number of blocks for the transaction to be confirmed. The accepted range is 1 - 1000 and the default value is 2. * @return array */ - public function estimateTransactionFees(int $numBlocks = null) + public function estimateTransactionFees(?int $numBlocks = null) { $this->url = $this->APIEndpoint . '/tx/fee'; $this->params = [