@kaleidorg/wallet-engine 1.0.0-beta.38 → 1.0.0-beta.41
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapters/flashnet.d.ts +1 -0
- package/dist/adapters/flashnet.d.ts.map +1 -1
- package/dist/adapters/flashnet.js +3 -0
- package/dist/adapters/flashnet.js.map +1 -1
- package/dist/adapters/wdk/ArkadeWdkAdapter.d.ts +42 -7
- package/dist/adapters/wdk/ArkadeWdkAdapter.d.ts.map +1 -1
- package/dist/adapters/wdk/ArkadeWdkAdapter.js +271 -61
- package/dist/adapters/wdk/ArkadeWdkAdapter.js.map +1 -1
- package/dist/adapters/wdk/RlnWdkAdapter.d.ts +21 -1
- package/dist/adapters/wdk/RlnWdkAdapter.d.ts.map +1 -1
- package/dist/adapters/wdk/RlnWdkAdapter.js +54 -1
- package/dist/adapters/wdk/RlnWdkAdapter.js.map +1 -1
- package/dist/adapters/wdk/SparkWdkAdapter.d.ts +70 -27
- package/dist/adapters/wdk/SparkWdkAdapter.d.ts.map +1 -1
- package/dist/adapters/wdk/SparkWdkAdapter.js +653 -170
- package/dist/adapters/wdk/SparkWdkAdapter.js.map +1 -1
- package/dist/format.d.ts +11 -0
- package/dist/format.d.ts.map +1 -0
- package/dist/format.js +10 -0
- package/dist/format.js.map +1 -0
- package/dist/lib/spark-client-manager.d.ts +9 -0
- package/dist/lib/spark-client-manager.d.ts.map +1 -1
- package/dist/lib/spark-client-manager.js +15 -0
- package/dist/lib/spark-client-manager.js.map +1 -1
- package/dist/lib/wallet-seed.d.ts +31 -0
- package/dist/lib/wallet-seed.d.ts.map +1 -0
- package/dist/lib/wallet-seed.js +58 -0
- package/dist/lib/wallet-seed.js.map +1 -0
- package/package.json +16 -18
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"flashnet.d.ts","sourceRoot":"","sources":["../../src/adapters/flashnet.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAA;AACtE,cAAc,yBAAyB,CAAA"}
|
|
1
|
+
{"version":3,"file":"flashnet.d.ts","sourceRoot":"","sources":["../../src/adapters/flashnet.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAA;AACtE,cAAc,yBAAyB,CAAA;AAGvC,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA"}
|
|
@@ -11,4 +11,7 @@
|
|
|
11
11
|
*/
|
|
12
12
|
export { flashnetClientManager } from '../lib/flashnet-client-manager.js';
|
|
13
13
|
export * from '../lib/orchestra-client.js';
|
|
14
|
+
// Re-export the SDK error guard so consumers classify Flashnet errors through
|
|
15
|
+
// the engine (no direct `@flashnet/sdk` dependency in the host).
|
|
16
|
+
export { isFlashnetError } from '@flashnet/sdk';
|
|
14
17
|
//# sourceMappingURL=flashnet.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"flashnet.js","sourceRoot":"","sources":["../../src/adapters/flashnet.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAA;AACtE,cAAc,yBAAyB,CAAA"}
|
|
1
|
+
{"version":3,"file":"flashnet.js","sourceRoot":"","sources":["../../src/adapters/flashnet.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAA;AACtE,cAAc,yBAAyB,CAAA;AACvC,8EAA8E;AAC9E,iEAAiE;AACjE,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA"}
|
|
@@ -7,19 +7,22 @@
|
|
|
7
7
|
* receive via Boltz reverse submarine swaps.
|
|
8
8
|
*
|
|
9
9
|
* Discipline: no WDK/@arkade-os types cross the contract — domain types only;
|
|
10
|
-
* module objects are read as `any`.
|
|
10
|
+
* module objects are read as `any`. The WDK **account** surface is the primary path;
|
|
11
|
+
* the underlying @arkade-os/sdk Wallet (`account._signingWallet`) is reached only for
|
|
12
|
+
* the VTXO-lifecycle ops the WDK surface does not expose (getVtxos, getBoardingUtxos,
|
|
13
|
+
* onboard, offboard, rich balance summary) — ported from the native ArkadeAdapter.
|
|
14
|
+
* `@arkade-os/sdk` is lazy-loaded in `connect()` so this sub-path stays SDK-free until used.
|
|
11
15
|
*
|
|
12
|
-
* Arkade WDK surface (from JSDoc
|
|
16
|
+
* Arkade WDK surface (from JSDoc, v0.1.4):
|
|
13
17
|
* read-only: getAddress(): string (Ark address, inherited), getBoardingAddress(): string,
|
|
14
18
|
* getBalance(): bigint, getTokenBalance(id): bigint, getTransactionHistory()
|
|
15
19
|
* account: sendTransaction({to,value}), transfer({token,recipient,amount}),
|
|
16
20
|
* createLightningInvoice(amountSats, description?): {invoice,paymentHash},
|
|
17
21
|
* waitForLightningPayment(invoice): {txid}, getLightningLimits/Fees,
|
|
18
|
-
* subscribeToIncomingFunds, sign, dispose
|
|
19
|
-
* NOTE: Lightning *send* (pay a BOLT11) is not exposed as a simple method in v0.1.3.
|
|
22
|
+
* arkadeSwaps (Boltz client, for Lightning send), subscribeToIncomingFunds, sign, dispose
|
|
20
23
|
*/
|
|
21
24
|
import { IProtocolAdapter, BaseProtocolConfig } from '../IProtocolAdapter.js';
|
|
22
|
-
import { ProtocolType, Layer, UnifiedAsset, UnifiedTransaction, InvoiceRequest, Invoice, DecodedInvoice, PaymentRequest, PaymentResult, PaymentStatus, Address, ConnectionInfo, TransactionFilter } from '../../types/base.js';
|
|
25
|
+
import { ProtocolType, Layer, NodeInfo, UnifiedAsset, UnifiedTransaction, InvoiceRequest, Invoice, DecodedInvoice, PaymentRequest, PaymentResult, PaymentStatus, Address, ConnectionInfo, TransactionFilter } from '../../types/base.js';
|
|
23
26
|
import { BaseWdkAdapter } from './BaseWdkAdapter.js';
|
|
24
27
|
export interface ArkadeAdapterConfig extends BaseProtocolConfig {
|
|
25
28
|
protocol: 'ARKADE';
|
|
@@ -34,10 +37,16 @@ export declare class ArkadeWdkAdapter extends BaseWdkAdapter implements IProtoco
|
|
|
34
37
|
readonly protocolName: ProtocolType;
|
|
35
38
|
readonly capabilities: readonly import("../../index.js").ProtocolCapability[];
|
|
36
39
|
readonly supportedLayers: Layer[];
|
|
40
|
+
/** BIP-39 mnemonic — retained for message signing (derives its own key). */
|
|
41
|
+
private mnemonic;
|
|
42
|
+
/** Lazily-loaded `@arkade-os/sdk` (for Ramps onboard/offboard). Kept off the static import graph. */
|
|
43
|
+
private arkSdk;
|
|
44
|
+
/** The underlying @arkade-os/sdk Wallet the WDK account wraps — for VTXO-lifecycle ops. */
|
|
45
|
+
private get rawWallet();
|
|
37
46
|
connect(config: BaseProtocolConfig): Promise<void>;
|
|
38
47
|
getConnectionInfo(): Promise<ConnectionInfo>;
|
|
39
48
|
/** Default Ark address. For the on-chain boarding address use `getBoardingAddress`. */
|
|
40
|
-
getReceiveAddress(
|
|
49
|
+
getReceiveAddress(assetId?: string): Promise<Address>;
|
|
41
50
|
/** On-chain BTC boarding address for funding the Arkade account. */
|
|
42
51
|
getBoardingAddress(): Promise<Address>;
|
|
43
52
|
getBtcBalance(): Promise<{
|
|
@@ -49,7 +58,14 @@ export declare class ArkadeWdkAdapter extends BaseWdkAdapter implements IProtoco
|
|
|
49
58
|
listAssets(): Promise<UnifiedAsset[]>;
|
|
50
59
|
getAssetBalance(assetId: string): Promise<UnifiedAsset['balance']>;
|
|
51
60
|
getAsset(assetId: string): Promise<UnifiedAsset>;
|
|
61
|
+
/** Arkade on-chain receive is an address, not a bolt11 invoice (mirrors the native adapter). */
|
|
52
62
|
createInvoice(request: InvoiceRequest): Promise<Invoice>;
|
|
63
|
+
/**
|
|
64
|
+
* Boltz reverse-swap Lightning invoice that lands funds in this Arkade wallet as a
|
|
65
|
+
* VTXO. Requires amount > 0 (Boltz can't issue an amountless invoice). The embedded
|
|
66
|
+
* SwapManager claims the VHTLC automatically once the LN payment settles.
|
|
67
|
+
*/
|
|
68
|
+
createArkadeLightningInvoice(request: InvoiceRequest): Promise<Invoice>;
|
|
53
69
|
decodeInvoice(invoice: string): Promise<DecodedInvoice>;
|
|
54
70
|
sendPayment(request: PaymentRequest): Promise<PaymentResult>;
|
|
55
71
|
/** Arkade BTC send/offboard. Bitcoin destinations settle on-chain asynchronously. */
|
|
@@ -67,11 +83,30 @@ export declare class ArkadeWdkAdapter extends BaseWdkAdapter implements IProtoco
|
|
|
67
83
|
getPaymentStatus(paymentHash: string): Promise<PaymentStatus>;
|
|
68
84
|
listTransactions(_filter?: TransactionFilter): Promise<UnifiedTransaction[]>;
|
|
69
85
|
getTransaction(txId: string): Promise<UnifiedTransaction>;
|
|
70
|
-
getNodeInfo(): Promise<
|
|
86
|
+
getNodeInfo(): Promise<NodeInfo>;
|
|
71
87
|
listChannels(): Promise<any[]>;
|
|
72
88
|
listPayments(): Promise<any>;
|
|
73
89
|
listTransfers(): Promise<any>;
|
|
90
|
+
/** All VTXOs, sorted by batchExpiry ascending (expiry-first) so soon-to-expire coins surface first. */
|
|
91
|
+
getVtxos(): Promise<Record<string, unknown>[]>;
|
|
92
|
+
getBoardingUtxos(): Promise<Record<string, unknown>[]>;
|
|
93
|
+
/** Onboard — settle confirmed boarding UTXOs into VTXOs via a Commitment Transaction. */
|
|
94
|
+
onboard(): Promise<{
|
|
95
|
+
txid: string;
|
|
96
|
+
}>;
|
|
97
|
+
/** Offboard — collaborative exit: convert VTXOs back to an on-chain Bitcoin UTXO. */
|
|
98
|
+
offboard(address: string, amount?: number): Promise<{
|
|
99
|
+
txid: string;
|
|
100
|
+
}>;
|
|
101
|
+
signMessage(message: string): Promise<string>;
|
|
102
|
+
verifyMessage(message: string, signature: string): Promise<string>;
|
|
74
103
|
/** Escape hatch for Arkade-specific ops (waitForLightningPayment, getLightningLimits, …) — allowlisted. */
|
|
75
104
|
executeProtocolOperation(operation: string, params: any): Promise<any>;
|
|
105
|
+
/**
|
|
106
|
+
* Rich balance summary derived from VTXOs + boarding UTXOs (ported from the native
|
|
107
|
+
* adapter). The SDK's top-level `balance.total` omits the boarding portion, so we
|
|
108
|
+
* recompute it: available = settled + preconfirmed; total includes boarding + recoverable.
|
|
109
|
+
*/
|
|
110
|
+
private getWalletBalanceSummary;
|
|
76
111
|
}
|
|
77
112
|
//# sourceMappingURL=ArkadeWdkAdapter.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ArkadeWdkAdapter.d.ts","sourceRoot":"","sources":["../../../src/adapters/wdk/ArkadeWdkAdapter.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"ArkadeWdkAdapter.d.ts","sourceRoot":"","sources":["../../../src/adapters/wdk/ArkadeWdkAdapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -7,16 +7,19 @@
|
|
|
7
7
|
* receive via Boltz reverse submarine swaps.
|
|
8
8
|
*
|
|
9
9
|
* Discipline: no WDK/@arkade-os types cross the contract — domain types only;
|
|
10
|
-
* module objects are read as `any`.
|
|
10
|
+
* module objects are read as `any`. The WDK **account** surface is the primary path;
|
|
11
|
+
* the underlying @arkade-os/sdk Wallet (`account._signingWallet`) is reached only for
|
|
12
|
+
* the VTXO-lifecycle ops the WDK surface does not expose (getVtxos, getBoardingUtxos,
|
|
13
|
+
* onboard, offboard, rich balance summary) — ported from the native ArkadeAdapter.
|
|
14
|
+
* `@arkade-os/sdk` is lazy-loaded in `connect()` so this sub-path stays SDK-free until used.
|
|
11
15
|
*
|
|
12
|
-
* Arkade WDK surface (from JSDoc
|
|
16
|
+
* Arkade WDK surface (from JSDoc, v0.1.4):
|
|
13
17
|
* read-only: getAddress(): string (Ark address, inherited), getBoardingAddress(): string,
|
|
14
18
|
* getBalance(): bigint, getTokenBalance(id): bigint, getTransactionHistory()
|
|
15
19
|
* account: sendTransaction({to,value}), transfer({token,recipient,amount}),
|
|
16
20
|
* createLightningInvoice(amountSats, description?): {invoice,paymentHash},
|
|
17
21
|
* waitForLightningPayment(invoice): {txid}, getLightningLimits/Fees,
|
|
18
|
-
* subscribeToIncomingFunds, sign, dispose
|
|
19
|
-
* NOTE: Lightning *send* (pay a BOLT11) is not exposed as a simple method in v0.1.3.
|
|
22
|
+
* arkadeSwaps (Boltz client, for Lightning send), subscribeToIncomingFunds, sign, dispose
|
|
20
23
|
*/
|
|
21
24
|
import { ProtocolError, } from '../../types/base.js';
|
|
22
25
|
import { getCapabilities } from '../../capabilities/index.js';
|
|
@@ -24,10 +27,18 @@ import { BaseWdkAdapter } from './BaseWdkAdapter.js';
|
|
|
24
27
|
import { PROTOCOL_OPERATIONS } from '../../capabilities/operations.js';
|
|
25
28
|
import { loadWdkModule } from './moduleLoader.js';
|
|
26
29
|
import { decodeBolt11, isBolt11 } from '../../lib/bolt11.js';
|
|
30
|
+
import { normalizeVtxos, sortVtxosByExpiry, toNumber } from '../../lib/arkade-helpers.js';
|
|
31
|
+
import { signLnMessage, verifyLnMessage } from '../../lib/ln-message-sign.js';
|
|
32
|
+
import { resolveWalletSeed } from '../../lib/wallet-seed.js';
|
|
27
33
|
const isBitcoinAddress = (value) => /^(bc1|tb1|bcrt1)/i.test(value.trim());
|
|
34
|
+
const isLightningInvoice = (value) => {
|
|
35
|
+
const body = value.trim().toLowerCase().replace(/^lightning:/, '');
|
|
36
|
+
return /^ln(bc|tb|bcrt|sb)/.test(body);
|
|
37
|
+
};
|
|
28
38
|
/**
|
|
29
39
|
* Allowlist of Arkade account methods reachable via `executeProtocolOperation`.
|
|
30
|
-
*
|
|
40
|
+
* VTXO-lifecycle ops (onboard/offboard/getVtxos/getBoardingUtxos) are now typed
|
|
41
|
+
* adapter methods, so they are intentionally NOT here.
|
|
31
42
|
*/
|
|
32
43
|
const ARKADE_ALLOWED_OPS = new Set([
|
|
33
44
|
'waitForLightningPayment',
|
|
@@ -37,10 +48,6 @@ const ARKADE_ALLOWED_OPS = new Set([
|
|
|
37
48
|
'getBoardingAddress',
|
|
38
49
|
'getTokenBalance',
|
|
39
50
|
'getTransactionHistory',
|
|
40
|
-
'onboard',
|
|
41
|
-
'offboard',
|
|
42
|
-
'getVtxos',
|
|
43
|
-
'getBoardingUtxos',
|
|
44
51
|
]);
|
|
45
52
|
export class ArkadeWdkAdapter extends BaseWdkAdapter {
|
|
46
53
|
constructor() {
|
|
@@ -48,29 +55,67 @@ export class ArkadeWdkAdapter extends BaseWdkAdapter {
|
|
|
48
55
|
this.protocolName = 'ARKADE';
|
|
49
56
|
this.capabilities = PROTOCOL_OPERATIONS.ARKADE;
|
|
50
57
|
this.supportedLayers = getCapabilities('ARKADE').layers;
|
|
58
|
+
/** BIP-39 mnemonic — retained for message signing (derives its own key). */
|
|
59
|
+
this.mnemonic = null;
|
|
60
|
+
/** Lazily-loaded `@arkade-os/sdk` (for Ramps onboard/offboard). Kept off the static import graph. */
|
|
61
|
+
this.arkSdk = null;
|
|
62
|
+
}
|
|
63
|
+
/** The underlying @arkade-os/sdk Wallet the WDK account wraps — for VTXO-lifecycle ops. */
|
|
64
|
+
get rawWallet() {
|
|
65
|
+
const w = this.account?._signingWallet ?? this.account?._wallet;
|
|
66
|
+
if (!w)
|
|
67
|
+
throw new ProtocolError('Arkade wallet unavailable', 'ARKADE', 'NOT_CONNECTED');
|
|
68
|
+
return w;
|
|
51
69
|
}
|
|
52
70
|
// --- Connection ---------------------------------------------------------
|
|
53
71
|
async connect(config) {
|
|
54
72
|
const cfg = config;
|
|
55
73
|
if (!cfg.mnemonic)
|
|
56
74
|
throw new ProtocolError('ArkadeWdkAdapter requires a mnemonic', 'ARKADE', 'CONFIG');
|
|
75
|
+
this.mnemonic = cfg.mnemonic;
|
|
57
76
|
this.network = cfg.network ?? 'mainnet';
|
|
77
|
+
// Accept either an explicit `arkadeConfig` passthrough OR the native adapter's
|
|
78
|
+
// flat fields (arkServerUrl/esploraUrl/swapProviderUrl) — so hosts can switch
|
|
79
|
+
// to this adapter without reshaping their connect config. The WDK manager
|
|
80
|
+
// spreads this straight into @arkade-os/sdk's Wallet.create.
|
|
81
|
+
const arkadeConfig = cfg.arkadeConfig ??
|
|
82
|
+
{
|
|
83
|
+
...(cfg.arkServerUrl ? { arkServerUrl: cfg.arkServerUrl } : {}),
|
|
84
|
+
...(cfg.esploraUrl ? { esploraUrl: cfg.esploraUrl } : {}),
|
|
85
|
+
...(cfg.swapProviderUrl ? { swapProviderUrl: cfg.swapProviderUrl } : {}),
|
|
86
|
+
};
|
|
58
87
|
// @ts-ignore — external module, resolved at runtime in the consuming app.
|
|
59
88
|
const mod = await loadWdkModule('@arkade-os/wdk', () => import('@arkade-os/wdk'));
|
|
60
89
|
const WalletManagerArkade = mod.default ?? mod.WalletManagerArkade ?? mod;
|
|
61
|
-
|
|
90
|
+
// Resolve to seed bytes so nsec/hex-rooted wallets bypass the WDK base's
|
|
91
|
+
// BIP-39 string validation (which throws "The seed phrase is invalid").
|
|
92
|
+
this.manager = new WalletManagerArkade(resolveWalletSeed(cfg.mnemonic), arkadeConfig);
|
|
62
93
|
this.account = await this.manager.getAccount(cfg.accountIndex ?? 0);
|
|
94
|
+
// Lazy-load the SDK for Ramps (onboard/offboard). Off the static import graph.
|
|
95
|
+
// @ts-ignore — resolved at runtime; a transitive dep of the WDK Arkade module.
|
|
96
|
+
this.arkSdk = await loadWdkModule('@arkade-os/sdk', () => import('@arkade-os/sdk'));
|
|
63
97
|
this.connected = true;
|
|
64
98
|
}
|
|
65
99
|
async getConnectionInfo() {
|
|
66
|
-
|
|
100
|
+
this.assertConnected();
|
|
101
|
+
return {
|
|
102
|
+
protocol: 'ARKADE',
|
|
103
|
+
connected: this.connected,
|
|
104
|
+
network: this.network,
|
|
105
|
+
syncStatus: { synced: true, progress: 100 },
|
|
106
|
+
};
|
|
67
107
|
}
|
|
68
108
|
// --- Address / receive --------------------------------------------------
|
|
69
109
|
/** Default Ark address. For the on-chain boarding address use `getBoardingAddress`. */
|
|
70
|
-
async getReceiveAddress(
|
|
110
|
+
async getReceiveAddress(assetId) {
|
|
71
111
|
this.assertConnected();
|
|
112
|
+
// 'onchain'/'boarding' → on-chain boarding address for funding.
|
|
113
|
+
if (assetId === 'onchain' || assetId === 'boarding') {
|
|
114
|
+
const address = await this.account.getBoardingAddress();
|
|
115
|
+
return { address, format: 'BTC_ADDRESS', asset: 'BTC' };
|
|
116
|
+
}
|
|
72
117
|
const address = await this.account.getAddress();
|
|
73
|
-
return { address, format: 'ARKADE_ADDRESS' };
|
|
118
|
+
return { address, format: 'ARKADE_ADDRESS', asset: assetId && assetId !== 'BTC' ? assetId : 'BTC' };
|
|
74
119
|
}
|
|
75
120
|
/** On-chain BTC boarding address for funding the Arkade account. */
|
|
76
121
|
async getBoardingAddress() {
|
|
@@ -81,33 +126,40 @@ export class ArkadeWdkAdapter extends BaseWdkAdapter {
|
|
|
81
126
|
// --- Balance ------------------------------------------------------------
|
|
82
127
|
async getBtcBalance() {
|
|
83
128
|
this.assertConnected();
|
|
84
|
-
const
|
|
85
|
-
|
|
86
|
-
|
|
129
|
+
const b = await this.getWalletBalanceSummary();
|
|
130
|
+
// preconfirmed VTXOs are spendable, so `confirmed` = settled + preconfirmed.
|
|
131
|
+
const confirmed = b.available;
|
|
132
|
+
return { confirmed, unconfirmed: Math.max(b.total - confirmed, 0), total: b.total };
|
|
87
133
|
}
|
|
88
134
|
async refreshBalances() {
|
|
89
135
|
// Arkade syncs against the indexer on read; no explicit sync call.
|
|
90
136
|
}
|
|
91
137
|
async listAssets() {
|
|
92
138
|
this.assertConnected();
|
|
93
|
-
const
|
|
139
|
+
const b = await this.getWalletBalanceSummary();
|
|
94
140
|
const btc = {
|
|
95
141
|
id: 'BTC',
|
|
96
|
-
name: 'Bitcoin',
|
|
142
|
+
name: 'Bitcoin (Arkade)',
|
|
97
143
|
ticker: 'BTC',
|
|
98
144
|
precision: 8,
|
|
99
145
|
protocol: 'ARKADE',
|
|
100
146
|
layer: 'BTC_ARKADE',
|
|
101
|
-
balance: {
|
|
102
|
-
|
|
147
|
+
balance: {
|
|
148
|
+
total: b.total,
|
|
149
|
+
available: b.available,
|
|
150
|
+
pending: 0,
|
|
151
|
+
locked: 0,
|
|
152
|
+
totalDisplay: String(b.total),
|
|
153
|
+
availableDisplay: String(b.available),
|
|
154
|
+
},
|
|
155
|
+
capabilities: { canSend: true, canReceive: true, canSwap: false, supportsLightning: false, supportsOnchain: true },
|
|
156
|
+
metadata: { boarding: b.boardingTotal, settled: b.settled, preconfirmed: b.preconfirmed, recoverable: b.recoverable },
|
|
103
157
|
};
|
|
104
158
|
const out = [btc];
|
|
105
|
-
// Arkade tokens.
|
|
106
|
-
//
|
|
107
|
-
// discovery does NOT come from getVtxos(). Resolve metadata (decimals /
|
|
108
|
-
// ticker / name) via `assetManager.getAssetDetails(assetId).metadata`.
|
|
159
|
+
// Arkade tokens. The wallet's `getBalance()` includes `assets: { assetId, amount }[]`;
|
|
160
|
+
// resolve metadata via `assetManager.getAssetDetails(assetId).metadata`.
|
|
109
161
|
try {
|
|
110
|
-
const wallet = this.
|
|
162
|
+
const wallet = this.rawWallet;
|
|
111
163
|
const rawBalance = wallet?.getBalance ? await wallet.getBalance() : null;
|
|
112
164
|
const rawAssets = Array.isArray(rawBalance?.assets) ? rawBalance.assets : [];
|
|
113
165
|
for (const entry of rawAssets) {
|
|
@@ -120,11 +172,11 @@ export class ArkadeWdkAdapter extends BaseWdkAdapter {
|
|
|
120
172
|
meta = (await wallet?.assetManager?.getAssetDetails?.(assetId))?.metadata ?? {};
|
|
121
173
|
}
|
|
122
174
|
catch {
|
|
123
|
-
|
|
175
|
+
/* metadata lookup is optional */
|
|
124
176
|
}
|
|
125
177
|
const decimals = Number(meta.decimals ?? 0) || 0;
|
|
126
|
-
const ticker =
|
|
127
|
-
const name =
|
|
178
|
+
const ticker = typeof meta.ticker === 'string' && meta.ticker.trim() ? meta.ticker : assetId.slice(0, 6);
|
|
179
|
+
const name = typeof meta.name === 'string' && meta.name.trim() ? meta.name : ticker;
|
|
128
180
|
out.push({
|
|
129
181
|
id: assetId,
|
|
130
182
|
name,
|
|
@@ -132,51 +184,66 @@ export class ArkadeWdkAdapter extends BaseWdkAdapter {
|
|
|
132
184
|
precision: decimals,
|
|
133
185
|
protocol: 'ARKADE',
|
|
134
186
|
layer: 'ARKADE_ARKADE',
|
|
135
|
-
balance: {
|
|
136
|
-
total: amount,
|
|
137
|
-
available: amount,
|
|
138
|
-
pending: 0,
|
|
139
|
-
totalDisplay: String(amount),
|
|
140
|
-
availableDisplay: String(amount),
|
|
141
|
-
},
|
|
187
|
+
balance: { total: amount, available: amount, pending: 0, totalDisplay: String(amount), availableDisplay: String(amount) },
|
|
142
188
|
icon: typeof meta.icon === 'string' ? meta.icon : undefined,
|
|
143
189
|
capabilities: { canSend: true, canReceive: true, canSwap: false, supportsLightning: false, supportsOnchain: false },
|
|
144
190
|
});
|
|
145
191
|
}
|
|
146
192
|
}
|
|
147
193
|
catch {
|
|
148
|
-
|
|
194
|
+
/* token enumeration is best-effort — keep BTC even if unavailable */
|
|
149
195
|
}
|
|
150
196
|
return out;
|
|
151
197
|
}
|
|
152
198
|
async getAssetBalance(assetId) {
|
|
153
199
|
this.assertConnected();
|
|
200
|
+
if (assetId === 'BTC' || assetId.toLowerCase() === 'btc') {
|
|
201
|
+
const { balance } = await this.getAsset('BTC').then((a) => ({ balance: a.balance }));
|
|
202
|
+
return balance;
|
|
203
|
+
}
|
|
154
204
|
const bal = await this.account.getTokenBalance(assetId);
|
|
155
205
|
const n = Number(bal);
|
|
156
206
|
return { total: n, available: n, pending: 0, totalDisplay: String(n), availableDisplay: String(n) };
|
|
157
207
|
}
|
|
158
208
|
async getAsset(assetId) {
|
|
159
209
|
const assets = await this.listAssets();
|
|
160
|
-
const found = assets.find((a) => a.id === assetId);
|
|
210
|
+
const found = assets.find((a) => a.id === assetId || a.ticker === assetId);
|
|
161
211
|
if (!found)
|
|
162
212
|
throw new ProtocolError(`Unknown asset ${assetId}`, 'ARKADE', 'NO_ASSET');
|
|
163
213
|
return found;
|
|
164
214
|
}
|
|
165
215
|
// --- Invoices -----------------------------------------------------------
|
|
216
|
+
/** Arkade on-chain receive is an address, not a bolt11 invoice (mirrors the native adapter). */
|
|
166
217
|
async createInvoice(request) {
|
|
167
218
|
this.assertConnected();
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
219
|
+
const address = await this.account.getAddress();
|
|
220
|
+
return {
|
|
221
|
+
invoice: address,
|
|
222
|
+
paymentHash: '',
|
|
223
|
+
amount: request.amount,
|
|
224
|
+
expiresAt: Date.now() + (request.expirySeconds ?? 3600) * 1000,
|
|
225
|
+
description: request.description ?? 'Arkade receiving address',
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Boltz reverse-swap Lightning invoice that lands funds in this Arkade wallet as a
|
|
230
|
+
* VTXO. Requires amount > 0 (Boltz can't issue an amountless invoice). The embedded
|
|
231
|
+
* SwapManager claims the VHTLC automatically once the LN payment settles.
|
|
232
|
+
*/
|
|
233
|
+
async createArkadeLightningInvoice(request) {
|
|
234
|
+
this.assertConnected();
|
|
235
|
+
if (!request.amount || request.amount <= 0) {
|
|
236
|
+
throw new ProtocolError('Amount is required for Boltz Lightning invoices into Arkade', 'ARKADE', 'INVALID_AMOUNT');
|
|
178
237
|
}
|
|
179
|
-
|
|
238
|
+
// createLightningInvoice(amountSats, description?) — POSITIONAL args; via Boltz reverse swap.
|
|
239
|
+
const r = await this.account.createLightningInvoice(request.amount, request.description);
|
|
240
|
+
return {
|
|
241
|
+
invoice: r?.invoice ?? '',
|
|
242
|
+
paymentHash: r?.paymentHash ?? '',
|
|
243
|
+
amount: request.amount,
|
|
244
|
+
expiresAt: Date.now() + (request.expirySeconds ?? 3600) * 1000,
|
|
245
|
+
description: request.description ?? 'Boltz reverse swap into Arkade',
|
|
246
|
+
};
|
|
180
247
|
}
|
|
181
248
|
async decodeInvoice(invoice) {
|
|
182
249
|
const dest = invoice.trim();
|
|
@@ -190,16 +257,36 @@ export class ArkadeWdkAdapter extends BaseWdkAdapter {
|
|
|
190
257
|
async sendPayment(request) {
|
|
191
258
|
this.assertConnected();
|
|
192
259
|
const dest = request.invoice.trim();
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
260
|
+
// Lightning send via Boltz submarine swap (Arkade → Lightning), if the account exposes the swap client.
|
|
261
|
+
if (isLightningInvoice(dest)) {
|
|
262
|
+
const swaps = this.account?.arkadeSwaps;
|
|
263
|
+
if (!swaps?.sendLightningPayment) {
|
|
264
|
+
throw new ProtocolError('Arkade Lightning send not available in this module version', 'ARKADE', 'NOT_SUPPORTED');
|
|
265
|
+
}
|
|
266
|
+
const invoiceBody = dest.toLowerCase().startsWith('lightning:') ? dest.slice('lightning:'.length) : dest;
|
|
267
|
+
try {
|
|
268
|
+
const result = await swaps.sendLightningPayment({ invoice: invoiceBody });
|
|
269
|
+
return {
|
|
270
|
+
paymentHash: result?.preimage ?? result?.txid ?? '',
|
|
271
|
+
amount: Number(result?.amount ?? request.amount ?? 0),
|
|
272
|
+
fee: 0,
|
|
273
|
+
status: 'pending',
|
|
274
|
+
timestamp: Date.now(),
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
catch (error) {
|
|
278
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
279
|
+
if (/less than minimal/i.test(msg)) {
|
|
280
|
+
throw new ProtocolError("Arkade can't pay amountless Lightning invoices. Ask the recipient for an invoice with an amount.", 'ARKADE', 'INVALID_AMOUNT');
|
|
281
|
+
}
|
|
282
|
+
throw new ProtocolError(`Failed to send Lightning payment via Boltz: ${msg}`, 'ARKADE', 'SEND_PAYMENT_ERROR');
|
|
283
|
+
}
|
|
196
284
|
}
|
|
197
285
|
if (request.amount == null) {
|
|
198
286
|
throw new ProtocolError('Arkade send requires an explicit amount', 'ARKADE', 'NO_AMOUNT');
|
|
199
287
|
}
|
|
200
288
|
// Bitcoin destination → on-chain offboard. Route through sendBtcOnchain so the
|
|
201
|
-
// missing-tx-id guard and async `pending` status apply regardless of entry point
|
|
202
|
-
// (otherwise a BTC offboard with no hash would falsely report success).
|
|
289
|
+
// missing-tx-id guard and async `pending` status apply regardless of entry point.
|
|
203
290
|
if (isBitcoinAddress(dest)) {
|
|
204
291
|
return this.sendBtcOnchain({ address: dest, amount: request.amount });
|
|
205
292
|
}
|
|
@@ -251,11 +338,8 @@ export class ArkadeWdkAdapter extends BaseWdkAdapter {
|
|
|
251
338
|
// @arkade-os/sdk ArkTransaction shape:
|
|
252
339
|
// { key:{ arkTxid, commitmentTxid, boardingTxid }, type:'SENT'|'RECEIVED',
|
|
253
340
|
// amount(sats, net), settled(boolean), createdAt(ms since epoch) }.
|
|
254
|
-
// The txid lives on `key` (
|
|
255
|
-
//
|
|
256
|
-
// explicit `type`, not the amount sign (amount is reported as a magnitude).
|
|
257
|
-
// `createdAt` is already milliseconds; the old `* 1000` pushed every entry
|
|
258
|
-
// ~50k years into the future, breaking sort order and the displayed date.
|
|
341
|
+
// The txid lives on `key` (unused fields are empty strings, so pick the first
|
|
342
|
+
// NON-EMPTY one — `??` would stop at `''`). Direction is the explicit `type`.
|
|
259
343
|
const key = t?.key ?? {};
|
|
260
344
|
const id = t?.txid || key.arkTxid || key.commitmentTxid || key.boardingTxid || '';
|
|
261
345
|
const isSend = String(t?.type ?? '').toUpperCase() === 'SENT';
|
|
@@ -279,21 +363,147 @@ export class ArkadeWdkAdapter extends BaseWdkAdapter {
|
|
|
279
363
|
throw new ProtocolError(`Unknown tx ${txId}`, 'ARKADE', 'NO_TX');
|
|
280
364
|
return found;
|
|
281
365
|
}
|
|
366
|
+
// --- Node & balance -----------------------------------------------------
|
|
282
367
|
async getNodeInfo() {
|
|
283
|
-
|
|
368
|
+
this.assertConnected();
|
|
369
|
+
const b = await this.getWalletBalanceSummary();
|
|
370
|
+
const spendableSats = b.available;
|
|
371
|
+
return {
|
|
372
|
+
channelsBalanceMsat: spendableSats * 1000,
|
|
373
|
+
maxPayableMsat: spendableSats * 1000,
|
|
374
|
+
onchainBalanceMsat: b.boardingConfirmed * 1000,
|
|
375
|
+
pendingOnchainBalanceMsat: b.boardingUnconfirmed * 1000,
|
|
376
|
+
maxReceivableMsat: 0,
|
|
377
|
+
inboundLiquidityMsats: 0,
|
|
378
|
+
connectedPeers: [],
|
|
379
|
+
utxos: 0,
|
|
380
|
+
};
|
|
284
381
|
}
|
|
285
382
|
async listChannels() {
|
|
286
383
|
return []; // Arkade has no LN channels (LN via Boltz swaps)
|
|
287
384
|
}
|
|
288
385
|
async listPayments() {
|
|
289
|
-
|
|
386
|
+
const txs = await this.listTransactions();
|
|
387
|
+
return { payments: txs };
|
|
290
388
|
}
|
|
291
389
|
async listTransfers() {
|
|
292
|
-
return
|
|
390
|
+
return { transfers: [] };
|
|
391
|
+
}
|
|
392
|
+
// --- VTXO lifecycle -----------------------------------------------------
|
|
393
|
+
/** All VTXOs, sorted by batchExpiry ascending (expiry-first) so soon-to-expire coins surface first. */
|
|
394
|
+
async getVtxos() {
|
|
395
|
+
this.assertConnected();
|
|
396
|
+
const vtxos = await this.rawWallet.getVtxos();
|
|
397
|
+
return normalizeVtxos(sortVtxosByExpiry(vtxos)).map((vtxo) => ({
|
|
398
|
+
txid: vtxo.txid,
|
|
399
|
+
vout: vtxo.vout,
|
|
400
|
+
value: vtxo.value,
|
|
401
|
+
state: vtxo.state,
|
|
402
|
+
batchTxid: vtxo.batchTxid,
|
|
403
|
+
batchExpiry: vtxo.batchExpiry,
|
|
404
|
+
createdAt: vtxo.createdAt,
|
|
405
|
+
assets: vtxo.assets,
|
|
406
|
+
}));
|
|
407
|
+
}
|
|
408
|
+
async getBoardingUtxos() {
|
|
409
|
+
this.assertConnected();
|
|
410
|
+
const utxos = await this.rawWallet.getBoardingUtxos();
|
|
411
|
+
return (utxos ?? []).map((u) => ({
|
|
412
|
+
txid: u.txid,
|
|
413
|
+
vout: u.vout,
|
|
414
|
+
value: u.value,
|
|
415
|
+
confirmed: u.status?.confirmed ?? false,
|
|
416
|
+
}));
|
|
417
|
+
}
|
|
418
|
+
/** Onboard — settle confirmed boarding UTXOs into VTXOs via a Commitment Transaction. */
|
|
419
|
+
async onboard() {
|
|
420
|
+
this.assertConnected();
|
|
421
|
+
const wallet = this.rawWallet;
|
|
422
|
+
const info = await wallet.arkProvider.getInfo();
|
|
423
|
+
const commitmentTxid = await new this.arkSdk.Ramps(wallet).onboard(info.fees);
|
|
424
|
+
return { txid: commitmentTxid };
|
|
425
|
+
}
|
|
426
|
+
/** Offboard — collaborative exit: convert VTXOs back to an on-chain Bitcoin UTXO. */
|
|
427
|
+
async offboard(address, amount) {
|
|
428
|
+
this.assertConnected();
|
|
429
|
+
if (!address)
|
|
430
|
+
throw new ProtocolError('Destination address required for offboard', 'ARKADE', 'INVALID_ADDRESS');
|
|
431
|
+
if (amount !== undefined && (!Number.isInteger(amount) || amount <= 0)) {
|
|
432
|
+
throw new ProtocolError(`Invalid offboard amount: ${amount}`, 'ARKADE', 'INVALID_AMOUNT');
|
|
433
|
+
}
|
|
434
|
+
const wallet = this.rawWallet;
|
|
435
|
+
const info = await wallet.arkProvider.getInfo();
|
|
436
|
+
const exitTxid = await new this.arkSdk.Ramps(wallet).offboard(address, info.fees, amount !== undefined ? BigInt(amount) : undefined);
|
|
437
|
+
return { txid: exitTxid };
|
|
438
|
+
}
|
|
439
|
+
// --- Message signing ----------------------------------------------------
|
|
440
|
+
async signMessage(message) {
|
|
441
|
+
if (!this.mnemonic)
|
|
442
|
+
throw new ProtocolError('Wallet mnemonic not available', 'ARKADE', 'NOT_CONNECTED');
|
|
443
|
+
const { mnemonicToSeedSync } = await import('@scure/bip39');
|
|
444
|
+
const { HDKey } = await import('@scure/bip32');
|
|
445
|
+
const seed = mnemonicToSeedSync(this.mnemonic);
|
|
446
|
+
const node = HDKey.fromMasterSeed(seed).derive("m/138'/1");
|
|
447
|
+
if (!node.privateKey) {
|
|
448
|
+
throw new ProtocolError('Failed to derive message-signing key', 'ARKADE', 'KEY_DERIVATION_ERROR');
|
|
449
|
+
}
|
|
450
|
+
return signLnMessage(message, node.privateKey);
|
|
451
|
+
}
|
|
452
|
+
async verifyMessage(message, signature) {
|
|
453
|
+
return verifyLnMessage(message, signature);
|
|
293
454
|
}
|
|
294
455
|
/** Escape hatch for Arkade-specific ops (waitForLightningPayment, getLightningLimits, …) — allowlisted. */
|
|
295
456
|
async executeProtocolOperation(operation, params) {
|
|
296
457
|
return this.runAllowlistedOp(ARKADE_ALLOWED_OPS, operation, params);
|
|
297
458
|
}
|
|
459
|
+
// --- Private helpers ----------------------------------------------------
|
|
460
|
+
/**
|
|
461
|
+
* Rich balance summary derived from VTXOs + boarding UTXOs (ported from the native
|
|
462
|
+
* adapter). The SDK's top-level `balance.total` omits the boarding portion, so we
|
|
463
|
+
* recompute it: available = settled + preconfirmed; total includes boarding + recoverable.
|
|
464
|
+
*/
|
|
465
|
+
async getWalletBalanceSummary() {
|
|
466
|
+
const wallet = this.rawWallet;
|
|
467
|
+
const balance = await wallet.getBalance();
|
|
468
|
+
const normalized = {
|
|
469
|
+
boardingConfirmed: toNumber(balance?.boarding?.confirmed),
|
|
470
|
+
boardingUnconfirmed: toNumber(balance?.boarding?.unconfirmed),
|
|
471
|
+
boardingTotal: toNumber(balance?.boarding?.total),
|
|
472
|
+
settled: toNumber(balance?.settled),
|
|
473
|
+
preconfirmed: toNumber(balance?.preconfirmed),
|
|
474
|
+
available: toNumber(balance?.available),
|
|
475
|
+
recoverable: toNumber(balance?.recoverable),
|
|
476
|
+
total: toNumber(balance?.total),
|
|
477
|
+
};
|
|
478
|
+
let normalizedVtxos = [];
|
|
479
|
+
try {
|
|
480
|
+
normalizedVtxos = normalizeVtxos(await wallet.getVtxos());
|
|
481
|
+
}
|
|
482
|
+
catch {
|
|
483
|
+
/* fall back to wallet.getBalance() */
|
|
484
|
+
}
|
|
485
|
+
if (normalizedVtxos.length === 0) {
|
|
486
|
+
const available = normalized.settled + normalized.preconfirmed;
|
|
487
|
+
return { ...normalized, available, total: normalized.boardingTotal + available + normalized.recoverable };
|
|
488
|
+
}
|
|
489
|
+
const vtxoSummary = normalizedVtxos.reduce((summary, vtxo) => {
|
|
490
|
+
if (vtxo.state === 'swept')
|
|
491
|
+
summary.recoverable += vtxo.value;
|
|
492
|
+
else if (vtxo.state === 'preconfirmed')
|
|
493
|
+
summary.preconfirmed += vtxo.value;
|
|
494
|
+
else
|
|
495
|
+
summary.settled += vtxo.value;
|
|
496
|
+
return summary;
|
|
497
|
+
}, { settled: 0, preconfirmed: 0, recoverable: 0 });
|
|
498
|
+
const available = vtxoSummary.settled + vtxoSummary.preconfirmed;
|
|
499
|
+
return {
|
|
500
|
+
...normalized,
|
|
501
|
+
settled: vtxoSummary.settled,
|
|
502
|
+
preconfirmed: vtxoSummary.preconfirmed,
|
|
503
|
+
available,
|
|
504
|
+
recoverable: vtxoSummary.recoverable,
|
|
505
|
+
total: normalized.boardingTotal + available + vtxoSummary.recoverable,
|
|
506
|
+
};
|
|
507
|
+
}
|
|
298
508
|
}
|
|
299
509
|
//# sourceMappingURL=ArkadeWdkAdapter.js.map
|