1 year ago
#351961
Granit
"Can't Buy With This Account" POST Request Error When Using The Buys Endpoint To Buy Bitcoin
My goal is to try and get a Node app (written in Typescript) to buy bitcoin using my "GBP Wallet" (fiat account). I am currently trying this via using the Axios library, rather than any unofficial Coinbase client libraries out there. I am successfully able to get data that I need from the GET endpoints of the Coinbase API. However, with the following POST endpoint I get an error:
POST https://api.coinbase.com/v2/accounts/:account_id/buys
The error:
[ { id: 'invalid_request', message: "Can't buy with this account" } ]
Here is a simplified example of the code I am trying to run at the moment:
import * as crypto from 'crypto';
import axios, { AxiosError, AxiosRequestConfig, AxiosResponse, Method } from 'axios';
import * as dotenv from 'dotenv';
dotenv.config();
const timer = (ms: number) => new Promise(res => setTimeout(res, ms));
function isNumeric(str: string): boolean {
const noSpacesStr = str.replace(/\s/g, '');
return !isNaN(Number(noSpacesStr)) && noSpacesStr.length !== 0;
}
async function coinbaseApiRequest(url: string, method: Method, data?: any): Promise<AxiosResponse> {
if (process.env.COINBASE_API_KEY === undefined || process.env.COINBASE_API_SECRET === undefined) {
throw new Error('Missing credentials');
}
const stringData = JSON.stringify(data);
const timestamp = Math.floor(Date.now() / 1000);
const message = data === undefined ? timestamp.toString() + method + url : timestamp.toString() + method + url + stringData;
const signature = crypto.createHmac("sha256", process.env.COINBASE_API_SECRET).update(message).digest("hex");
const config: AxiosRequestConfig = {
method,
url: `https://api.coinbase.com${url}`,
headers: {
'CB-ACCESS-SIGN': signature,
'CB-ACCESS-TIMESTAMP': timestamp,
'CB-ACCESS-KEY': process.env.COINBASE_API_KEY,
'CB-VERSION': '2021-05-19',
'Content-Type': 'application/json'
},
data
};
return axios(config);
}
async function getBuyPrice(): Promise<AxiosResponse> {
return coinbaseApiRequest('/v2/prices/BTC-GBP/buy', 'GET');
}
async function getSellPrice(): Promise<AxiosResponse> {
return coinbaseApiRequest('/v2/prices/BTC-GBP/sell', 'GET');
}
async function getGBPAccount(): Promise<AxiosResponse> {
return coinbaseApiRequest('/v2/accounts/GBP', 'GET');
}
async function getBitcoinAccount(): Promise<AxiosResponse> {
return coinbaseApiRequest('/v2/accounts/BTC', 'GET');
}
async function getGBPWalletPaymentMethodID(): Promise<string> {
const paymentMethods = await coinbaseApiRequest('/v2/payment-methods', 'GET');
for (let i = 0; i < paymentMethods.data.data.length; i++) {
const paymentMethod = paymentMethods.data.data[i];
if (paymentMethod.name === 'GBP Wallet' && paymentMethod.type === 'fiat_account') {
return paymentMethod.id;
}
}
throw new Error('GBP wallet has not been found');
}
async function postBuyBitcoin(accountId: string, amount: string, paymentMethod: string): Promise<AxiosResponse> {
if (!isNumeric(amount)) { throw new Error('amount arg is not a valid number'); }
const body = { amount, currency: 'BTC', payment_method: paymentMethod };
return coinbaseApiRequest(`/v2/accounts/${accountId}/buys`, 'POST', body);
}
async function run(): Promise<void> {
try {
const oldGBPAccRes = await getGBPAccount();
const oldBTCAccRes = await getBitcoinAccount();
const paymentMethodID = await getGBPWalletPaymentMethodID();
const buyRes = await postBuyBitcoin(oldGBPAccRes.data.data.id, '0.00001', paymentMethodID);
const newGBPAccRes = await getGBPAccount();
const newBTCAccRes = await getBitcoinAccount();
console.log(`old GBP account response:`);
console.log(oldGBPAccRes.data);
console.log(`old BTC account response:`);
console.log(oldBTCAccRes.data);
console.log(`bitcoin buy response:`);
console.log(buyRes);
console.log(`new GBP account response:`);
console.log(newGBPAccRes.data);
console.log(`new BTC account response:`);
console.log(newBTCAccRes.data);
console.log('Finished payment');
} catch (error: any | AxiosError) {
if (axios.isAxiosError(error)) {
console.log(error.response?.data.errors);
}
}
}
run();
All the GET request functions seem to work fine and return the responses correctly when I run them individually. The only issue I have is with the POST request function. I get the following error logged when running the code above:
[ { id: 'invalid_request', message: "Can't buy with this account" } ]
Not sure why this is happening, and there does not seem to be much on this online relevant to node based implementations, but this seems to be somewhat related. would appreciate some guidance. Thanks in advance.
node.js
typescript
axios
coinbase-api
0 Answers
Your Answer