(self, path, api: Any = [], method='GET', params={}, headers: dict = None, body: Str = None)
| 4888 | return self.milliseconds() - self.options['timeDifference'] |
| 4889 | |
| 4890 | def sign(self, path, api: Any = [], method='GET', params={}, headers: dict = None, body: Str = None): |
| 4891 | version = api[0] |
| 4892 | signed = api[1] == 'private' |
| 4893 | isV3 = version == 'v3' |
| 4894 | pathPart = 'api/v3' if (isV3) else 'v2' |
| 4895 | fullPath = '/' + pathPart + '/' + self.implode_params(path, params) |
| 4896 | query = self.omit(params, self.extract_params(path)) |
| 4897 | savedPath = fullPath |
| 4898 | if method == 'GET': |
| 4899 | if query: |
| 4900 | fullPath += '?' + self.urlencode_with_array_repeat(query) |
| 4901 | url = self.urls['api']['rest'] + fullPath |
| 4902 | if signed: |
| 4903 | authorization = self.safe_string(self.headers, 'Authorization') |
| 4904 | authorizationString = None |
| 4905 | if authorization is not None: |
| 4906 | authorizationString = authorization |
| 4907 | elif self.token and not self.check_required_credentials(False): |
| 4908 | authorizationString = 'Bearer ' + self.token |
| 4909 | else: |
| 4910 | self.check_required_credentials() |
| 4911 | seconds = self.seconds() |
| 4912 | payload = '' |
| 4913 | if method != 'GET': |
| 4914 | if query: |
| 4915 | body = self.json(query) |
| 4916 | payload = body |
| 4917 | else: |
| 4918 | if not isV3: |
| 4919 | if query: |
| 4920 | payload += '?' + self.urlencode(query) |
| 4921 | # v3: 'GET' doesn't need payload in the signature. inside url is enough |
| 4922 | # https://docs.cdp.coinbase.com/coinbase-app/authentication-authorization/api-key-authentication |
| 4923 | # v2: 'GET' require payload in the signature |
| 4924 | # https://docs.cdp.coinbase.com/coinbase-app/authentication-authorization/api-key-authentication |
| 4925 | isCloudAPiKey = (self.apiKey.find('organizations/') >= 0) or (self.secret.startswith('-----BEGIN')) |
| 4926 | # using the size might be fragile, so we add an option to force v2 cloud api key if needed |
| 4927 | isV2CloudAPiKey = len(self.secret) == 88 or self.safe_bool(self.options, 'v2CloudAPiKey', False) or self.secret.endswith('=') |
| 4928 | if isCloudAPiKey or isV2CloudAPiKey: |
| 4929 | if isCloudAPiKey and self.apiKey.startswith('-----BEGIN'): |
| 4930 | raise ArgumentsRequired(self.id + ' apiKey should contain the name(eg: organizations/3b910e93....) and not the public key') |
| 4931 | # # it may not work for v2 |
| 4932 | # uri = method + ' ' + url.replace('https://', '') |
| 4933 | # quesPos = uri.find('?') |
| 4934 | # # Due to we use mb_strpos, quesPos could be False in php. In that case, the quesPos >= 0 is True |
| 4935 | # # Also it's not possible that the question mark is first character, only check > 0 here. |
| 4936 | # if quesPos > 0: |
| 4937 | # uri = uri[0:quesPos] |
| 4938 | # } |
| 4939 | # nonce = self.random_bytes(16) |
| 4940 | # request = { |
| 4941 | # 'aud': ['retail_rest_api_proxy'], |
| 4942 | # 'iss': 'coinbase-cloud', |
| 4943 | # 'nbf': seconds, |
| 4944 | # 'exp': seconds + 120, |
| 4945 | # 'sub': self.apiKey, |
| 4946 | # 'uri': uri, |
| 4947 | # 'iat': seconds, |
nothing calls this directly
no test coverage detected