fix: ark
This commit is contained in:
parent
aec787cd6e
commit
839a1a6595
@ -145,7 +145,6 @@ export class LightningArkWallet extends LightningCustodianWallet {
|
||||
setTimeout(async () => {
|
||||
const manager = new VtxoManager(staticWalletCache[namespace], {
|
||||
enabled: true, // Enable expiration monitoring
|
||||
thresholdPercentage: 10, // Alert when 10% of lifetime remains (default)
|
||||
});
|
||||
try {
|
||||
const txid = await manager.renewVtxos();
|
||||
|
||||
@ -8,7 +8,7 @@ module.exports = {
|
||||
moduleFileExtensions: ['js', 'json', 'ts', 'tsx'],
|
||||
transformIgnorePatterns: ['node_modules/(?!((jest-)?react-native(-.*)?|@react-native(-community)?)|@rneui|silent-payments|@arkade-os)/'],
|
||||
moduleNameMapper: {
|
||||
'^expo/fetch$': '<rootDir>/util/expo-fetch.js',
|
||||
'^expo/fetch$': '<rootDir>/util/expo-fetch-nodejs.js',
|
||||
},
|
||||
setupFiles: ['./tests/setup.js'],
|
||||
watchPathIgnorePatterns: ['<rootDir>/node_modules'],
|
||||
|
||||
26
package-lock.json
generated
26
package-lock.json
generated
@ -10,8 +10,8 @@
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@arkade-os/boltz-swap": "0.2.8",
|
||||
"@arkade-os/sdk": "0.3.5",
|
||||
"@arkade-os/boltz-swap": "0.2.9",
|
||||
"@arkade-os/sdk": "0.3.7",
|
||||
"@babel/preset-env": "7.27.2",
|
||||
"@bugsnag/react-native": "8.4.0",
|
||||
"@bugsnag/source-maps": "2.3.3",
|
||||
@ -169,13 +169,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@arkade-os/boltz-swap": {
|
||||
"version": "0.2.8",
|
||||
"resolved": "https://registry.npmjs.org/@arkade-os/boltz-swap/-/boltz-swap-0.2.8.tgz",
|
||||
"integrity": "sha512-N9NaLSPXgQ31+hayNbsPG9CkkfRI/a9jWEAtwxXZPd90qU+AAg9/NM8GuuWPd4yn4JLLf1TBR6oA92ylLnKLOQ==",
|
||||
"version": "0.2.9",
|
||||
"resolved": "https://registry.npmjs.org/@arkade-os/boltz-swap/-/boltz-swap-0.2.9.tgz",
|
||||
"integrity": "sha512-Y+P2MdYN9vhicQ1qqCzlPJIU+4bhWwlhDIbbiesbb72KtKpaDCfpTJPHrInMfy/LizJwE6nPJKSwVaFPqxo5Lg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@arkade-os/sdk": "0.3.5",
|
||||
"@noble/hashes": "2.0.0",
|
||||
"@arkade-os/sdk": "0.3.7",
|
||||
"@noble/hashes": "2.0.1",
|
||||
"@scure/base": "2.0.0",
|
||||
"@scure/btc-signer": "2.0.1",
|
||||
"light-bolt11-decoder": "3.2.0"
|
||||
@ -185,9 +185,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@arkade-os/boltz-swap/node_modules/@noble/hashes": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-2.0.0.tgz",
|
||||
"integrity": "sha512-h8VUBlE8R42+XIDO229cgisD287im3kdY6nbNZJFjc6ZvKIXPYXe6Vc/t+kyjFdMFyt5JpapzTsEg8n63w5/lw==",
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-2.0.1.tgz",
|
||||
"integrity": "sha512-XlOlEbQcE9fmuXxrVTXCTlG2nlRXa9Rj3rr5Ue/+tX+nmkgbX720YHh0VR3hBF9xDvwnb8D2shVGOwNx+ulArw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 20.19.0"
|
||||
@ -197,9 +197,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@arkade-os/sdk": {
|
||||
"version": "0.3.5",
|
||||
"resolved": "https://registry.npmjs.org/@arkade-os/sdk/-/sdk-0.3.5.tgz",
|
||||
"integrity": "sha512-e+y+rgclCA+ooGURFIKiBwAafEjgI+JEW7wlTAEF/THoDOZmT17VVBQPKWUa51jX9MJyBQ481jvq/lyuroVUnw==",
|
||||
"version": "0.3.7",
|
||||
"resolved": "https://registry.npmjs.org/@arkade-os/sdk/-/sdk-0.3.7.tgz",
|
||||
"integrity": "sha512-uXRf3uXc+YKZA0nnPe/gM6QKGTB4xlQn+EHPU3PliCp7fWTDYnPX/QzWszNY5Y71/FWMebrUgHFyDk6XnlQOrw==",
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
|
||||
@ -81,8 +81,8 @@
|
||||
"unit": "jest -b -w tests/unit/*"
|
||||
},
|
||||
"dependencies": {
|
||||
"@arkade-os/boltz-swap": "0.2.8",
|
||||
"@arkade-os/sdk": "0.3.5",
|
||||
"@arkade-os/boltz-swap": "0.2.9",
|
||||
"@arkade-os/sdk": "0.3.7",
|
||||
"@babel/preset-env": "7.27.2",
|
||||
"@bugsnag/react-native": "8.4.0",
|
||||
"@bugsnag/source-maps": "2.3.3",
|
||||
|
||||
350
util/expo-fetch-nodejs.js
Normal file
350
util/expo-fetch-nodejs.js
Normal file
@ -0,0 +1,350 @@
|
||||
// Node.js polyfill for expo/fetch
|
||||
// Minimal "expo/fetch" polyfill for Node.js using http/https modules
|
||||
// - Streaming via Response.body.getReader() and async iteration (for SSE)
|
||||
// - AbortController support
|
||||
// - credentials ('include' / 'same-origin') support
|
||||
// - Robust header normalization (Headers, arrays, Map, plain object)
|
||||
// - ESM + CJS interop (default + named exports)
|
||||
// - Throws only real Error instances
|
||||
|
||||
const http = require('http');
|
||||
const https = require('https');
|
||||
const { URL } = require('url');
|
||||
|
||||
class AbortError extends Error {
|
||||
constructor(message = 'Aborted') {
|
||||
super(message);
|
||||
this.name = 'AbortError';
|
||||
}
|
||||
}
|
||||
|
||||
class SimpleHeaders {
|
||||
constructor(init) {
|
||||
this._map = new Map();
|
||||
if (!init) return;
|
||||
if (typeof init === 'string') {
|
||||
init.split(/\r?\n/).forEach(line => {
|
||||
const i = line.indexOf(':');
|
||||
if (i > 0) {
|
||||
const k = line.slice(0, i).trim();
|
||||
const v = line.slice(i + 1).trim();
|
||||
if (k) this._map.set(k.toLowerCase(), v);
|
||||
}
|
||||
});
|
||||
} else if (typeof init === 'object' && init !== null) {
|
||||
if (typeof init.forEach === 'function' && typeof init.entries === 'function') {
|
||||
// WHATWG Headers-like
|
||||
for (const [k, v] of init.entries()) this._map.set(String(k).toLowerCase(), String(v));
|
||||
} else if (Array.isArray(init)) {
|
||||
for (const [k, v] of init) this._map.set(String(k).toLowerCase(), String(v));
|
||||
} else if (init instanceof Map) {
|
||||
for (const [k, v] of init) this._map.set(String(k).toLowerCase(), String(v));
|
||||
} else {
|
||||
for (const [k, v] of Object.entries(init)) this._map.set(String(k).toLowerCase(), String(v));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
get(name) {
|
||||
return this._map.get(String(name).toLowerCase()) ?? null;
|
||||
}
|
||||
|
||||
has(name) {
|
||||
return this._map.has(String(name).toLowerCase());
|
||||
}
|
||||
|
||||
forEach(cb) {
|
||||
for (const [k, v] of this._map) cb(v, k);
|
||||
}
|
||||
|
||||
entries() {
|
||||
return this._map.entries();
|
||||
}
|
||||
|
||||
set(name, value) {
|
||||
this._map.set(String(name).toLowerCase(), String(value));
|
||||
}
|
||||
|
||||
delete(name) {
|
||||
this._map.delete(String(name).toLowerCase());
|
||||
}
|
||||
|
||||
keys() {
|
||||
return this._map.keys();
|
||||
}
|
||||
|
||||
values() {
|
||||
return this._map.values();
|
||||
}
|
||||
|
||||
[Symbol.iterator]() {
|
||||
return this._map[Symbol.iterator]();
|
||||
}
|
||||
}
|
||||
|
||||
class StreamController {
|
||||
constructor() {
|
||||
this._q = [];
|
||||
this._pending = null;
|
||||
this._closed = false;
|
||||
this._err = null;
|
||||
}
|
||||
|
||||
push(bytes) {
|
||||
if (this._closed || this._err) return;
|
||||
if (this._pending) {
|
||||
const r = this._pending;
|
||||
this._pending = null;
|
||||
r({ value: bytes, done: false });
|
||||
} else this._q.push(bytes);
|
||||
}
|
||||
|
||||
close() {
|
||||
if (this._closed || this._err) return;
|
||||
this._closed = true;
|
||||
if (this._pending) {
|
||||
const r = this._pending;
|
||||
this._pending = null;
|
||||
r({ done: true });
|
||||
}
|
||||
}
|
||||
|
||||
error(e) {
|
||||
if (this._closed || this._err) return;
|
||||
this._err = e instanceof Error ? e : new Error(String(e));
|
||||
if (this._pending) {
|
||||
const r = this._pending;
|
||||
this._pending = null;
|
||||
r({ done: true });
|
||||
}
|
||||
}
|
||||
|
||||
getReader() {
|
||||
return {
|
||||
read: () => {
|
||||
if (this._err) return Promise.reject(this._err);
|
||||
if (this._q.length) return Promise.resolve({ value: this._q.shift(), done: false });
|
||||
if (this._closed) return Promise.resolve({ done: true });
|
||||
return new Promise(resolve => {
|
||||
this._pending = resolve;
|
||||
});
|
||||
},
|
||||
cancel: () => {
|
||||
this._q.length = 0;
|
||||
this.close();
|
||||
return Promise.resolve();
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
[Symbol.asyncIterator]() {
|
||||
const reader = this.getReader();
|
||||
return {
|
||||
next: () => reader.read(),
|
||||
return: () => reader.cancel().then(() => ({ done: true, value: undefined })),
|
||||
throw: e => {
|
||||
this.error(e);
|
||||
return Promise.resolve({ done: true, value: undefined });
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
class SimpleResponse {
|
||||
constructor({ url, status, statusText, headers, body }) {
|
||||
this.url = url;
|
||||
this.status = status;
|
||||
this.statusText = statusText || '';
|
||||
this.ok = status >= 200 && status < 300;
|
||||
this.headers = headers;
|
||||
this.body = body;
|
||||
this._text = null;
|
||||
this._buf = null;
|
||||
}
|
||||
|
||||
async arrayBuffer() {
|
||||
if (this._buf) return this._buf.buffer;
|
||||
const chunks = [];
|
||||
for await (const c of this.body) chunks.push(c);
|
||||
const total = chunks.reduce((s, c) => s + c.byteLength, 0);
|
||||
const out = new Uint8Array(total);
|
||||
let off = 0;
|
||||
for (const c of chunks) {
|
||||
out.set(c, off);
|
||||
off += c.byteLength;
|
||||
}
|
||||
this._buf = out;
|
||||
return out.buffer;
|
||||
}
|
||||
|
||||
async text() {
|
||||
if (this._text != null) return this._text;
|
||||
const dec = new TextDecoder();
|
||||
let t = '';
|
||||
for await (const c of this.body) t += dec.decode(c, { stream: true });
|
||||
t += dec.decode();
|
||||
this._text = t;
|
||||
return t;
|
||||
}
|
||||
|
||||
json() {
|
||||
return this.text().then(JSON.parse);
|
||||
}
|
||||
}
|
||||
|
||||
function normalizeHeaders(h) {
|
||||
const out = {};
|
||||
if (!h) return out;
|
||||
if (typeof h === 'object' && h !== null) {
|
||||
if (typeof h.forEach === 'function' && typeof h.entries === 'function') {
|
||||
for (const [k, v] of h.entries()) out[k] = String(v);
|
||||
} else if (Array.isArray(h)) {
|
||||
for (const [k, v] of h) out[k] = String(v);
|
||||
} else if (h instanceof Map) {
|
||||
for (const [k, v] of h) out[k] = String(v);
|
||||
} else {
|
||||
for (const [k, v] of Object.entries(h)) out[k] = String(v);
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
function fetchShim(input, init = {}) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const url = typeof input === 'string' ? input : input?.toString?.();
|
||||
if (!url) {
|
||||
reject(new Error('Invalid request URL'));
|
||||
return;
|
||||
}
|
||||
|
||||
let parsedUrl;
|
||||
try {
|
||||
parsedUrl = new URL(url);
|
||||
} catch (e) {
|
||||
reject(new Error(`Invalid URL: ${url}`));
|
||||
return;
|
||||
}
|
||||
|
||||
const method = (init.method || 'GET').toUpperCase();
|
||||
const headers = normalizeHeaders(init.headers);
|
||||
const body = init.body ?? null;
|
||||
|
||||
// Choose http or https module
|
||||
const client = parsedUrl.protocol === 'https:' ? https : http;
|
||||
|
||||
const controller = new StreamController();
|
||||
let resolved = false;
|
||||
let req;
|
||||
|
||||
const options = {
|
||||
method,
|
||||
hostname: parsedUrl.hostname,
|
||||
port: parsedUrl.port,
|
||||
path: parsedUrl.pathname + parsedUrl.search,
|
||||
headers,
|
||||
};
|
||||
|
||||
// credentials support
|
||||
if (init.credentials === 'include' || init.credentials === 'same-origin') {
|
||||
// In Node.js, this would typically mean including cookies
|
||||
// For most SSE use cases, this is handled by the Cookie header
|
||||
// If needed, you can add agent configuration here
|
||||
}
|
||||
|
||||
req = client.request(options, res => {
|
||||
// Build response headers
|
||||
const responseHeaders = new SimpleHeaders(res.headers);
|
||||
|
||||
// Resolve with response immediately (like XHR readyState 2)
|
||||
const response = new SimpleResponse({
|
||||
url,
|
||||
status: res.statusCode,
|
||||
statusText: res.statusMessage,
|
||||
headers: responseHeaders,
|
||||
body: controller,
|
||||
});
|
||||
|
||||
resolve(response);
|
||||
resolved = true;
|
||||
|
||||
// Stream response data
|
||||
res.on('data', chunk => {
|
||||
// Convert Buffer to Uint8Array
|
||||
const uint8 = new Uint8Array(chunk.buffer, chunk.byteOffset, chunk.byteLength);
|
||||
controller.push(uint8);
|
||||
});
|
||||
|
||||
res.on('end', () => {
|
||||
controller.close();
|
||||
});
|
||||
|
||||
res.on('error', err => {
|
||||
const error = err instanceof Error ? err : new Error(String(err));
|
||||
controller.error(error);
|
||||
});
|
||||
});
|
||||
|
||||
req.on('error', err => {
|
||||
const error = err instanceof Error ? err : new Error(String(err));
|
||||
controller.error(error);
|
||||
if (!resolved) reject(error);
|
||||
});
|
||||
|
||||
// AbortController support
|
||||
if (init.signal) {
|
||||
if (init.signal.aborted) {
|
||||
req.destroy();
|
||||
const err = new AbortError();
|
||||
controller.error(err);
|
||||
if (!resolved) reject(err);
|
||||
return;
|
||||
} else {
|
||||
init.signal.addEventListener(
|
||||
'abort',
|
||||
() => {
|
||||
req.destroy();
|
||||
const err = new AbortError();
|
||||
controller.error(err);
|
||||
if (!resolved) reject(err);
|
||||
},
|
||||
{ once: true },
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Send body
|
||||
try {
|
||||
if (body == null) {
|
||||
req.end();
|
||||
} else if (typeof body === 'string') {
|
||||
req.end(body);
|
||||
} else if (Buffer.isBuffer(body)) {
|
||||
req.end(body);
|
||||
} else if (body instanceof Uint8Array || ArrayBuffer.isView(body)) {
|
||||
req.end(Buffer.from(body.buffer, body.byteOffset, body.byteLength));
|
||||
} else if (body instanceof ArrayBuffer) {
|
||||
req.end(Buffer.from(body));
|
||||
} else {
|
||||
// Fallback: JSON
|
||||
const jsonBody = JSON.stringify(body);
|
||||
if (!headers['content-type']) {
|
||||
req.setHeader('Content-Type', 'application/json');
|
||||
}
|
||||
req.end(jsonBody);
|
||||
}
|
||||
} catch (e) {
|
||||
const err = e instanceof Error ? e : new Error(String(e));
|
||||
controller.error(err);
|
||||
if (!resolved) reject(err);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// ---- ESM exports
|
||||
module.exports = fetchShim;
|
||||
module.exports.default = fetchShim;
|
||||
module.exports.fetch = fetchShim;
|
||||
module.exports.Headers = SimpleHeaders;
|
||||
module.exports.Response = SimpleResponse;
|
||||
module.exports.AbortError = AbortError;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user