@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.
@@ -11,4 +11,5 @@
11
11
  */
12
12
  export { flashnetClientManager } from '../lib/flashnet-client-manager.js';
13
13
  export * from '../lib/orchestra-client.js';
14
+ export { isFlashnetError } from '@flashnet/sdk';
14
15
  //# sourceMappingURL=flashnet.d.ts.map
@@ -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 in the cloned source, v0.1.3):
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(_assetId?: string): Promise<Address>;
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<any>;
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":"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"}
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 in the cloned source, v0.1.3):
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
- * Anything not listed here is rejected — see the method's SECURITY note.
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
- this.manager = new WalletManagerArkade(cfg.mnemonic, cfg.arkadeConfig ?? {});
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
- return { protocol: 'ARKADE', connected: this.connected, network: this.network };
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(_assetId) {
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 bal = await this.account.getBalance();
85
- const total = Number(bal);
86
- return { confirmed: total, unconfirmed: 0, total };
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 { total } = await this.getBtcBalance();
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: { total, available: total, pending: 0, totalDisplay: String(total), availableDisplay: String(total) },
102
- capabilities: { canSend: true, canReceive: true, canSwap: false, supportsLightning: true, supportsOnchain: true },
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. Per the extension's working adapter, the wallet's
106
- // `getBalance()` already includes `assets: { assetId, amount }[]` — token
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.account?._wallet;
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
- // metadata lookup is optional — fall back to the raw id
175
+ /* metadata lookup is optional */
124
176
  }
125
177
  const decimals = Number(meta.decimals ?? 0) || 0;
126
- const ticker = (typeof meta.ticker === 'string' && meta.ticker.trim()) ? meta.ticker : assetId.slice(0, 6);
127
- const name = (typeof meta.name === 'string' && meta.name.trim()) ? meta.name : ticker;
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
- // token enumeration is best-effort — keep BTC even if balance is unavailable
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
- if (request.layer === 'BTC_LN' || request.amount != null) {
169
- // createLightningInvoice(amountSats, description?) — POSITIONAL args; via Boltz reverse swap.
170
- const r = await this.account.createLightningInvoice(request.amount ?? 0, request.description);
171
- return {
172
- invoice: r?.invoice ?? '',
173
- paymentHash: r?.paymentHash ?? '',
174
- amount: request.amount,
175
- expiresAt: Date.now() + (request.expirySeconds ?? 3600) * 1000,
176
- description: request.description,
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
- throw new ProtocolError('Arkade on-chain receive uses getReceiveAddress/getBoardingAddress', 'ARKADE', 'NOT_SUPPORTED');
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
- if (/^ln(bc|tb|bcrt)/i.test(dest)) {
194
- // Lightning send via Boltz submarine swap is not exposed as a simple method in v0.1.3.
195
- throw new ProtocolError('Arkade Lightning send not available in this module version', 'ARKADE', 'NOT_SUPPORTED');
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` (the unused fields are empty strings, so we must
255
- // pick the first NON-EMPTY one — `??` would stop at `''`). Direction is the
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
- return { protocol: 'ARKADE', network: this.network };
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
- return this.listTransactions();
386
+ const txs = await this.listTransactions();
387
+ return { payments: txs };
290
388
  }
291
389
  async listTransfers() {
292
- return this.account.getTransactionHistory();
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