Coinbase API BTC 账户丢失
Coinbase API BTC account missing
感谢您的帮助。
在使用币库API的过程中,当我调用
client.getAccounts({}, function(error, accounts){
console.log('accounts', accounts)
})
我注意到许多账户,包括以太坊、莱特币,但没有比特币 (BTC)
有人可以帮忙弄清楚为什么吗?
非常感谢!
由于某种原因比特币不在返回的主账户中。您可以使用此调用获取特定帐户。
btcAccount = client.get_account('BTC')
TL;DR
使用 yarn add rxjs
或 npm install rxjs
将 rxjs
添加到您的项目,然后执行此操作:
import { EMPTY, from, reduce, expand } from 'rxjs';
// Promisify: Wrap API call in a promise
const getAccountsAsync = (options) => {
return new Promise((resolve, reject) => {
client.getAccounts(options, (err, accounts, pagination) => {
if (err) return reject(err);
resolve({accounts, pagination});
})
})
}
// Number of accounts to fetch per request
const paginationLimit = 100;
from(getAccountsAsync({limit: paginationLimit})).pipe(
// As long as there is a next_uri set, continue recursion
expand(res => res.pagination.next_uri ?
getAccountsAsync({
limit: paginationLimit,
next_uri: res.pagination.next_uri,
starting_after: res.pagination.next_starting_after
}) :
EMPTY
),
// Filter and concatenate the result of all API calls
reduce((acc, current) => acc.concat(current.accounts.filter(account => account.balance.amount > 0)), [])
).subscribe(allAccounts => console.log(allAccounts));
说明
只有前 25 个帐户得到 returned 的原因是因为 coinbase API 使用分页,而 25 是默认页面大小(参见 official docs)。
当你调用 getAccounts()
时,你实际上得到了三个 return 值(即使 API 只指定了两个):
client.getAccounts({}, (err, accounts, pagination) => {});
分页对象看起来像这样:
{
ending_before: null,
starting_after: null,
previous_ending_before: null,
next_starting_after: 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX',
limit: 25,
order: 'desc',
previous_uri: null,
next_uri: '/v2/accounts?limit=25&starting_after=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'
}
您可以像这样增加限制:
client.getAccounts({limit: 100}, (err, accounts, pagination) => {});
但是coinbase目前有175个账户(币种),我们可以提供的最大分页数限制为100。
因此,为了获取其余页面,我们必须进行额外的 API 调用,提供 starting_after
和 next_uri
作为选项,如下所示:
client.getAccounts({
limit: 100,
next_uri: '/v2/accounts?limit=100&starting_after=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX',
starting_after: 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'
}, (err, accounts, pagination) => {});
next_uri
旁注
当已经有 starting_after
时,我们必须提供 next_uri
似乎是多余的。其实docs不用说我们要提供next_uri
。但是,如果我省略此值,则会出现以下错误:
ClientError [AuthenticationError]: invalid signature
在深入研究 source code 之后,我发现在检查是否设置了 starting_after
之前,他们会检查是否设置了 next_uri
。所以,显然我们必须提供这个值。
解决方案 1 - 递归承诺
要打印您的所有帐户(balance.amount > 0
处的帐户),我们可以先将 API 调用包装在一个承诺中,然后使用递归。可能的解决方案如下所示:
// Promisify: Wrap API call in a promise
const getAccountsAsync = (options) => {
return new Promise((resolve, reject) => {
client.getAccounts(options, (err, accounts, pagination) => {
if (err) return reject(err);
resolve({accounts, pagination});
})
})
}
// Fetch all accounts recursively
const fetchAllAccounts = (nextUri, lastFetchedId) => {
getAccountsAsync({limit: 100, next_uri: nextUri, starting_after: lastFetchedId})
.then(res => {
// Print your accounts from current batch
res.accounts.forEach(account => {
if (account.balance.amount > 0) {
console.log(account)
}
});
// Terminate recursion when next_uri is empty
if (res.pagination.next_uri != null) {
// Call next batch of 100 accounts, starting after lastFetchedId
fetchAllAccounts(res.pagination.next_uri, res.pagination.next_starting_after)
}
})
.catch(err => console.log(err));
};
// Initial call
fetchAllAccounts(null, null);
不幸的是,使用这种方法,帐户分布在多个回调中。我们不能轻易与他们合作。如果你想对你的帐户做更多的事情,而不仅仅是将它们打印到控制台,你可以使用 RxJS.
解决方案 2 - 使用 RxJS
更优雅的解决方案是使用 RxJS 中的 expand 函数。同样,我们必须先将 API 调用包装在一个 promise 中。
使用 yarn add rxjs
或 npm install rxjs
将 rxjs
添加到您的项目,然后执行此操作:
import { EMPTY, from, reduce, expand } from 'rxjs';
// Promisify: Wrap API call in a promise
const getAccountsAsync = (options) => {
return new Promise((resolve, reject) => {
client.getAccounts(options, (err, accounts, pagination) => {
if (err) return reject(err);
resolve({accounts, pagination});
})
})
}
// Number of accounts to fetch per request
const paginationLimit = 100;
from(getAccountsAsync({limit: paginationLimit})).pipe(
// As long as there is a next_uri set, continue recursion
expand(res => res.pagination.next_uri ?
getAccountsAsync({
limit: paginationLimit,
next_uri: res.pagination.next_uri,
starting_after: res.pagination.next_starting_after
}) :
EMPTY
),
// Filter and concatenate the result of all API calls
reduce((acc, current) => acc.concat(current.accounts.filter(account => account.balance.amount > 0)), [])
).subscribe(allAccounts => console.log(allAccounts));
这种方法的优点是,我们可以连接所有 API 调用的结果并将它们合并到一个数组中。
感谢您的帮助。
在使用币库API的过程中,当我调用
client.getAccounts({}, function(error, accounts){
console.log('accounts', accounts)
})
我注意到许多账户,包括以太坊、莱特币,但没有比特币 (BTC)
有人可以帮忙弄清楚为什么吗?
非常感谢!
由于某种原因比特币不在返回的主账户中。您可以使用此调用获取特定帐户。
btcAccount = client.get_account('BTC')
TL;DR
使用 yarn add rxjs
或 npm install rxjs
将 rxjs
添加到您的项目,然后执行此操作:
import { EMPTY, from, reduce, expand } from 'rxjs';
// Promisify: Wrap API call in a promise
const getAccountsAsync = (options) => {
return new Promise((resolve, reject) => {
client.getAccounts(options, (err, accounts, pagination) => {
if (err) return reject(err);
resolve({accounts, pagination});
})
})
}
// Number of accounts to fetch per request
const paginationLimit = 100;
from(getAccountsAsync({limit: paginationLimit})).pipe(
// As long as there is a next_uri set, continue recursion
expand(res => res.pagination.next_uri ?
getAccountsAsync({
limit: paginationLimit,
next_uri: res.pagination.next_uri,
starting_after: res.pagination.next_starting_after
}) :
EMPTY
),
// Filter and concatenate the result of all API calls
reduce((acc, current) => acc.concat(current.accounts.filter(account => account.balance.amount > 0)), [])
).subscribe(allAccounts => console.log(allAccounts));
说明
只有前 25 个帐户得到 returned 的原因是因为 coinbase API 使用分页,而 25 是默认页面大小(参见 official docs)。
当你调用 getAccounts()
时,你实际上得到了三个 return 值(即使 API 只指定了两个):
client.getAccounts({}, (err, accounts, pagination) => {});
分页对象看起来像这样:
{
ending_before: null,
starting_after: null,
previous_ending_before: null,
next_starting_after: 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX',
limit: 25,
order: 'desc',
previous_uri: null,
next_uri: '/v2/accounts?limit=25&starting_after=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'
}
您可以像这样增加限制:
client.getAccounts({limit: 100}, (err, accounts, pagination) => {});
但是coinbase目前有175个账户(币种),我们可以提供的最大分页数限制为100。
因此,为了获取其余页面,我们必须进行额外的 API 调用,提供 starting_after
和 next_uri
作为选项,如下所示:
client.getAccounts({
limit: 100,
next_uri: '/v2/accounts?limit=100&starting_after=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX',
starting_after: 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'
}, (err, accounts, pagination) => {});
next_uri
当已经有 starting_after
时,我们必须提供 next_uri
似乎是多余的。其实docs不用说我们要提供next_uri
。但是,如果我省略此值,则会出现以下错误:
ClientError [AuthenticationError]: invalid signature
在深入研究 source code 之后,我发现在检查是否设置了 starting_after
之前,他们会检查是否设置了 next_uri
。所以,显然我们必须提供这个值。
解决方案 1 - 递归承诺
要打印您的所有帐户(balance.amount > 0
处的帐户),我们可以先将 API 调用包装在一个承诺中,然后使用递归。可能的解决方案如下所示:
// Promisify: Wrap API call in a promise
const getAccountsAsync = (options) => {
return new Promise((resolve, reject) => {
client.getAccounts(options, (err, accounts, pagination) => {
if (err) return reject(err);
resolve({accounts, pagination});
})
})
}
// Fetch all accounts recursively
const fetchAllAccounts = (nextUri, lastFetchedId) => {
getAccountsAsync({limit: 100, next_uri: nextUri, starting_after: lastFetchedId})
.then(res => {
// Print your accounts from current batch
res.accounts.forEach(account => {
if (account.balance.amount > 0) {
console.log(account)
}
});
// Terminate recursion when next_uri is empty
if (res.pagination.next_uri != null) {
// Call next batch of 100 accounts, starting after lastFetchedId
fetchAllAccounts(res.pagination.next_uri, res.pagination.next_starting_after)
}
})
.catch(err => console.log(err));
};
// Initial call
fetchAllAccounts(null, null);
不幸的是,使用这种方法,帐户分布在多个回调中。我们不能轻易与他们合作。如果你想对你的帐户做更多的事情,而不仅仅是将它们打印到控制台,你可以使用 RxJS.
解决方案 2 - 使用 RxJS
更优雅的解决方案是使用 RxJS 中的 expand 函数。同样,我们必须先将 API 调用包装在一个 promise 中。
使用 yarn add rxjs
或 npm install rxjs
将 rxjs
添加到您的项目,然后执行此操作:
import { EMPTY, from, reduce, expand } from 'rxjs';
// Promisify: Wrap API call in a promise
const getAccountsAsync = (options) => {
return new Promise((resolve, reject) => {
client.getAccounts(options, (err, accounts, pagination) => {
if (err) return reject(err);
resolve({accounts, pagination});
})
})
}
// Number of accounts to fetch per request
const paginationLimit = 100;
from(getAccountsAsync({limit: paginationLimit})).pipe(
// As long as there is a next_uri set, continue recursion
expand(res => res.pagination.next_uri ?
getAccountsAsync({
limit: paginationLimit,
next_uri: res.pagination.next_uri,
starting_after: res.pagination.next_starting_after
}) :
EMPTY
),
// Filter and concatenate the result of all API calls
reduce((acc, current) => acc.concat(current.accounts.filter(account => account.balance.amount > 0)), [])
).subscribe(allAccounts => console.log(allAccounts));
这种方法的优点是,我们可以连接所有 API 调用的结果并将它们合并到一个数组中。