Интеграция с Anchorage Digital
Anchorage Digital — первый federally chartered crypto bank в США (OCC charter, 2021). Для продуктов, которые работают с институциональными клиентами или требуют банковского уровня кастодии, Anchorage — серьёзный вариант. Не нужно строить собственную кастодиальную инфраструктуру, получать отдельные лицензии на хранение, договариваться со страховщиками — всё это Anchorage берёт на себя. Интеграция через их API позволяет встроить institutional-grade custody прямо в ваш продукт.
Что даёт интеграция
Anchorage предоставляет REST API для управления:
- Custody — хранение активов с аппаратной изоляцией ключей (HSM-based, не pure software)
- Transactions — создание, подписание и вещание on-chain транзакций через кастодиальный pipeline
- Staking — делегирование для PoS активов (ETH, SOL, MATIC, ADA и другие) с отчётностью
- Trading — OTC trading desk интеграция
- Governance — on-chain голосование от имени кастодированных активов
API построен по REST принципам, аутентификация через JWT + API ключи. Sandbox среда доступна для разработки.
Архитектура интеграции
Аутентификация и безопасность
Anchorage использует двухуровневую аутентификацию: API ключ + подпись запроса. Каждый запрос должен быть подписан приватным ключом, публичный аналог которого зарегистрирован в системе:
import crypto from "crypto";
interface AnchorageRequestSigner {
apiKeyId: string;
privateKey: string; // PEM формат, ECDSA P-256
}
function signRequest(
signer: AnchorageRequestSigner,
method: string,
path: string,
body: object | null,
timestamp: number
): string {
const bodyString = body ? JSON.stringify(body) : "";
const payload = `${timestamp}${method}${path}${bodyString}`;
const sign = crypto.createSign("SHA256");
sign.update(payload);
const signature = sign.sign(signer.privateKey, "base64");
return `Signature keyId="${signer.apiKeyId}",algorithm="ecdsa-p256",signature="${signature}"`;
}
async function anchorageRequest(
signer: AnchorageRequestSigner,
method: string,
path: string,
body?: object
): Promise<Response> {
const timestamp = Math.floor(Date.now() / 1000);
const authHeader = signRequest(signer, method, path, body ?? null, timestamp);
return fetch(`https://api.anchorage.com${path}`, {
method,
headers: {
"Content-Type": "application/json",
"Api-Access-Key": signer.apiKeyId,
"Authorization": authHeader,
"X-Timestamp": String(timestamp),
},
body: body ? JSON.stringify(body) : undefined,
});
}
Создание транзакции и workflow подтверждений
Транзакции в Anchorage проходят через configurable approval workflow. Это не просто "отправить и забыть" — в зависимости от настроек vault'а транзакция может требовать подтверждения от нескольких операторов, мобильного приложения Anchorage (out-of-band approval), или автоматически исполняться если проходит policy rules.
interface CreateTransactionRequest {
vaultId: string;
assetType: string; // "ETHEREUM", "BITCOIN", "SOLANA" и т.д.
destinationAddress: string;
amount: string; // в базовых единицах (wei для ETH)
note?: string;
externalTxId?: string; // ваш внутренний ID для идемпотентности
}
async function createWithdrawal(
signer: AnchorageRequestSigner,
request: CreateTransactionRequest
): Promise<{ transactionId: string; status: string }> {
const response = await anchorageRequest(
signer, "POST", "/v2/transactions", request
);
if (!response.ok) {
const error = await response.json();
throw new Error(`Anchorage API error: ${error.message}`);
}
return response.json();
}
// Polling статуса — транзакция проходит через PENDING_APPROVAL → APPROVED → BROADCASTING → DONE
async function waitForTransaction(
signer: AnchorageRequestSigner,
transactionId: string,
timeoutMs = 300_000
): Promise<string> {
const start = Date.now();
while (Date.now() - start < timeoutMs) {
const response = await anchorageRequest(
signer, "GET", `/v2/transactions/${transactionId}`
);
const tx = await response.json();
if (tx.status === "DONE") return tx.txHash;
if (["FAILED", "REJECTED"].includes(tx.status)) {
throw new Error(`Transaction ${tx.status}: ${tx.rejectionReason}`);
}
await new Promise(resolve => setTimeout(resolve, 5000));
}
throw new Error("Transaction polling timeout");
}
Работа с балансами и адресами
Anchorage организует активы в vaults (логические хранилища) и wallets (адреса конкретных активов внутри vault). Для каждого клиента обычно создаётся отдельный vault:
// Получить баланс конкретного актива в vault
async function getVaultBalance(
signer: AnchorageRequestSigner,
vaultId: string,
assetType: string
): Promise<{ available: string; total: string }> {
const response = await anchorageRequest(
signer, "GET", `/v2/vaults/${vaultId}/assets/${assetType}`
);
const asset = await response.json();
return {
available: asset.availableBalance,
total: asset.totalBalance,
};
}
// Получить deposit адрес для пополнения
async function getDepositAddress(
signer: AnchorageRequestSigner,
vaultId: string,
assetType: string
): Promise<string> {
const response = await anchorageRequest(
signer, "GET", `/v2/vaults/${vaultId}/assets/${assetType}/addresses`
);
const data = await response.json();
return data.addresses[0].address;
}
Типичные сценарии интеграции
Exchange / торговая платформа — кастодия средств пользователей в Anchorage vault'ах, вывод через Transaction API с approval workflow, депозиты через webhook уведомления о входящих транзакциях.
Fund administrator — создание отдельного vault на каждый фонд, staking через Anchorage Earn, reporting через Transaction history API.
Corporate treasury — управление treasury в нескольких активах, автоматические ребалансировки через API, аудит trail для compliance.
Ограничения и что нужно знать
Anchorage — не самообслуживание. Интеграция начинается с enterprise sales процесса, KYB, подписания договора. Sandbox доступен после initial approval. Pricing — по договорённости, как правило basis points от AUM + фиксированная плата за транзакции.
Transaction finality зависит от approval policy: если настроен manual approval, время от создания до исполнения может составлять часы. Это нужно учитывать в UX — пользователь должен понимать, что вывод не мгновенный.
Поддерживаемые активы постоянно расширяются, но экзотические L2 токены могут отсутствовать. Проверяйте актуальный список через /v2/assets endpoint перед проектированием.







