Some checks failed
CI/CD Pipeline / Solidity Contracts (push) Failing after 59s
CI/CD Pipeline / Security Scanning (push) Successful in 2m34s
CI/CD Pipeline / Lint and Format (push) Failing after 49s
CI/CD Pipeline / Terraform Validation (push) Failing after 22s
CI/CD Pipeline / Kubernetes Validation (push) Successful in 26s
HYBX OMNL TypeScript & anchor / token-aggregation build + reconcile artifact (push) Failing after 19s
Validation / validate-genesis (push) Successful in 31s
Validation / validate-terraform (push) Failing after 27s
Validation / validate-kubernetes (push) Failing after 10s
Validation / validate-smart-contracts (push) Failing after 12s
Validation / validate-security (push) Failing after 1m26s
Validation / validate-documentation (push) Failing after 18s
Wire Business/Platform/Spot adapters with fail-closed live gates, status/probe/dispatch APIs, smoke script, and portal rails UI. Co-authored-by: Cursor <cursoragent@cursor.com>
143 lines
5.3 KiB
JavaScript
143 lines
5.3 KiB
JavaScript
"use strict";
|
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
};
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.WisePlatformRail = void 0;
|
|
exports.loadWiseConfig = loadWiseConfig;
|
|
/**
|
|
* Wise Platform API (production) — profiles / quotes / transfers.
|
|
* Docs: https://docs.wise.com/api-docs
|
|
* Auth: Bearer personal/business API token.
|
|
*/
|
|
const axios_1 = __importDefault(require("axios"));
|
|
function loadWiseConfig() {
|
|
const apiToken = (process.env.WISE_API_TOKEN || process.env.TRANSFERWISE_API_TOKEN || '').trim();
|
|
const baseUrl = (process.env.WISE_API_BASE_URL ||
|
|
process.env.TRANSFERWISE_API_BASE_URL ||
|
|
'https://api.transferwise.com').replace(/\/$/, '');
|
|
return {
|
|
baseUrl,
|
|
apiToken,
|
|
profileId: (process.env.WISE_PROFILE_ID || process.env.TRANSFERWISE_PROFILE_ID || '').trim() || undefined,
|
|
enabled: Boolean(apiToken) && process.env.WISE_ENABLED !== '0',
|
|
};
|
|
}
|
|
class WisePlatformRail {
|
|
config;
|
|
http;
|
|
constructor(cfg = loadWiseConfig()) {
|
|
this.config = cfg;
|
|
this.http = axios_1.default.create({
|
|
baseURL: cfg.baseUrl,
|
|
timeout: 60000,
|
|
headers: {
|
|
Authorization: `Bearer ${cfg.apiToken}`,
|
|
Accept: 'application/json',
|
|
'Content-Type': 'application/json',
|
|
},
|
|
});
|
|
}
|
|
isReady() {
|
|
return this.config.enabled && Boolean(this.config.apiToken);
|
|
}
|
|
async listProfiles() {
|
|
const { data } = await this.http.get('/v1/profiles');
|
|
return Array.isArray(data) ? data : [];
|
|
}
|
|
async resolveProfileId() {
|
|
if (this.config.profileId)
|
|
return this.config.profileId;
|
|
const profiles = await this.listProfiles();
|
|
const first = profiles[0];
|
|
if (!first?.id)
|
|
throw new Error('Wise profile not found — set WISE_PROFILE_ID');
|
|
return String(first.id);
|
|
}
|
|
async createQuote(payload) {
|
|
if (!this.isReady())
|
|
throw new Error('Wise not configured (WISE_API_TOKEN)');
|
|
const profileId = await this.resolveProfileId();
|
|
const body = {
|
|
profile: Number(profileId) || profileId,
|
|
sourceCurrency: payload.sourceCurrency.toUpperCase(),
|
|
targetCurrency: payload.targetCurrency.toUpperCase(),
|
|
payOut: 'BANK_TRANSFER',
|
|
};
|
|
if (payload.sourceAmount)
|
|
body.sourceAmount = Number(payload.sourceAmount);
|
|
else if (payload.targetAmount)
|
|
body.targetAmount = Number(payload.targetAmount);
|
|
else
|
|
throw new Error('sourceAmount or targetAmount required');
|
|
const { data } = await this.http.post('/v3/quotes', body);
|
|
return {
|
|
quoteId: String(data?.id ?? data?.uuid ?? ''),
|
|
rate: data?.rate != null ? Number(data.rate) : undefined,
|
|
raw: data,
|
|
};
|
|
}
|
|
async createRecipient(payload) {
|
|
const profileId = await this.resolveProfileId();
|
|
const currency = payload.currency.toUpperCase();
|
|
const type = payload.type || (payload.iban ? 'iban' : 'email');
|
|
const details = {};
|
|
if (payload.iban) {
|
|
details.IBAN = payload.iban;
|
|
if (payload.bic)
|
|
details.BIC = payload.bic;
|
|
}
|
|
const { data } = await this.http.post('/v1/accounts', {
|
|
profile: Number(profileId) || profileId,
|
|
accountHolderName: payload.accountHolderName,
|
|
currency,
|
|
type,
|
|
details,
|
|
});
|
|
return { accountId: Number(data?.id), raw: data };
|
|
}
|
|
async createTransfer(payload) {
|
|
if (!this.isReady())
|
|
throw new Error('Wise not configured (WISE_API_TOKEN)');
|
|
const { data } = await this.http.post('/v1/transfers', {
|
|
targetAccount: payload.targetAccountId,
|
|
quoteUuid: payload.quoteId,
|
|
customerTransactionId: payload.idempotencyKey.slice(0, 36),
|
|
details: { reference: payload.reference || 'OMNL Z Online Bank' },
|
|
});
|
|
return {
|
|
transferId: String(data?.id ?? payload.idempotencyKey),
|
|
status: String(data?.status ?? 'incoming_payment_waiting'),
|
|
raw: data,
|
|
};
|
|
}
|
|
/** Full payout: quote → recipient → transfer (fund separately if required). */
|
|
async payout(payload) {
|
|
const source = payload.currency.toUpperCase();
|
|
const target = (payload.targetCurrency || payload.currency).toUpperCase();
|
|
const quote = await this.createQuote({
|
|
sourceCurrency: source,
|
|
targetCurrency: target,
|
|
sourceAmount: payload.amount,
|
|
});
|
|
const recipient = await this.createRecipient({
|
|
currency: target,
|
|
accountHolderName: payload.beneficiaryName,
|
|
iban: payload.iban,
|
|
bic: payload.bic,
|
|
});
|
|
const transfer = await this.createTransfer({
|
|
idempotencyKey: payload.idempotencyKey,
|
|
quoteId: quote.quoteId,
|
|
targetAccountId: recipient.accountId,
|
|
reference: payload.reference,
|
|
});
|
|
return {
|
|
transferId: transfer.transferId,
|
|
status: transfer.status,
|
|
quoteId: quote.quoteId,
|
|
};
|
|
}
|
|
}
|
|
exports.WisePlatformRail = WisePlatformRail;
|