@lombard.finance/sdk-solana 1.2.2 → 2.0.0
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/README.md +48 -15
- package/dist/index.cjs +1 -1
- package/dist/index.js +37 -31
- package/dist/index2.cjs +57 -54
- package/dist/index2.js +7608 -7206
- package/package.json +2 -2
- package/src/const/errors.ts +0 -4
- package/src/const/getConfig.ts +43 -20
- package/src/const/rpcUrls.ts +2 -2
- package/src/idl/asset_router.json +548 -179
- package/src/idl/consortium.json +24 -43
- package/src/idl/mailbox.json +118 -107
- package/src/index.ts +1 -3
- package/src/services/SolanaServiceImpl.test.ts +123 -0
- package/src/services/SolanaServiceImpl.ts +53 -17
- package/src/stories/components/OutputSelector/OutputSelector.tsx +1 -0
- package/src/types/errors.ts +2 -0
- package/src/utils/createDebugLogger.ts +6 -13
- package/src/utils/errors.ts +2 -0
- package/src/utils/tokenAccount.ts +3 -1
- package/src/utils/transactions.ts +1 -1
- package/src/web3Sdk/claimToken/claimBtcb.ts +37 -28
- package/src/web3Sdk/claimToken/claimLbtcGmp.ts +66 -8
- package/src/web3Sdk/claimToken/claimToken.stories.tsx +2 -2
- package/src/web3Sdk/claimToken/claimToken.ts +20 -16
- package/src/web3Sdk/claimToken/constants.ts +5 -0
- package/src/web3Sdk/claimToken/index.ts +1 -0
- package/src/web3Sdk/claimToken/shared.ts +88 -80
- package/src/web3Sdk/deposit/deposit.stories.tsx +240 -0
- package/src/web3Sdk/deposit/deposit.test.ts +327 -0
- package/src/web3Sdk/deposit/deposit.ts +339 -0
- package/src/web3Sdk/deposit/index.ts +1 -0
- package/src/web3Sdk/getTokenFeeConfig/getTokenFeeConfig.stories.tsx +166 -0
- package/src/web3Sdk/getTokenFeeConfig/getTokenFeeConfig.test.ts +224 -0
- package/src/web3Sdk/getTokenFeeConfig/getTokenFeeConfig.ts +154 -0
- package/src/web3Sdk/getTokenFeeConfig/index.ts +11 -0
- package/src/web3Sdk/index.ts +3 -4
- package/src/web3Sdk/redeem/index.ts +1 -0
- package/src/web3Sdk/redeem/redeem.stories.tsx +226 -0
- package/src/web3Sdk/redeem/redeem.test.ts +327 -0
- package/src/web3Sdk/redeem/redeem.ts +352 -0
- package/src/web3Sdk/redeemToken/redeemBtcb.ts +174 -0
- package/src/web3Sdk/redeemToken/redeemForBtc.stories.tsx +35 -21
- package/src/web3Sdk/redeemToken/redeemForBtc.test.ts +306 -0
- package/src/web3Sdk/redeemToken/redeemForBtc.ts +54 -215
- package/src/web3Sdk/redeemToken/redeemLbtc.ts +174 -0
- package/src/web3Sdk/redeemToken/shared.test.ts +45 -0
- package/src/web3Sdk/redeemToken/shared.ts +97 -0
- package/src/web3Sdk/claimLBTC/claimLBTC.stories.tsx +0 -189
- package/src/web3Sdk/claimLBTC/claimLBTC.ts +0 -225
- package/src/web3Sdk/claimLBTC/index.ts +0 -1
- package/src/web3Sdk/claimLBTC/utils/generateDepositId.ts +0 -75
- package/src/web3Sdk/claimLBTC/utils/index.ts +0 -2
- package/src/web3Sdk/claimLBTC/utils/parseTransactionLogs.ts +0 -44
- package/src/web3Sdk/claimLBTC/utils/payloadUtils.ts +0 -58
- package/src/web3Sdk/claimLBTC/utils/postMintSignatures.ts +0 -50
- package/src/web3Sdk/unstakeLBTC/index.ts +0 -1
- package/src/web3Sdk/unstakeLBTC/unstakeLBTC.stories.tsx +0 -141
- package/src/web3Sdk/unstakeLBTC/unstakeLBTC.ts +0 -140
- /package/src/web3Sdk/{claimLBTC → claimToken}/utils/__tests__/signatureUtils.test.ts +0 -0
- /package/src/web3Sdk/{claimLBTC → claimToken}/utils/signatureUtils.ts +0 -0
|
@@ -11,7 +11,7 @@ import { sha256 } from 'js-sha256';
|
|
|
11
11
|
import { IConfig } from '../../const/getConfig';
|
|
12
12
|
import { ISolanaWalletProvider, SolanaNetwork } from '../../types';
|
|
13
13
|
import { sendAndConfirmTransaction } from '../../utils';
|
|
14
|
-
import { parseSignaturesFromProof } from '
|
|
14
|
+
import { parseSignaturesFromProof } from './utils/signatureUtils';
|
|
15
15
|
|
|
16
16
|
// ── PDA seeds ──
|
|
17
17
|
|
|
@@ -137,83 +137,62 @@ export function getConsortiumSessionPDA(
|
|
|
137
137
|
}
|
|
138
138
|
|
|
139
139
|
/**
|
|
140
|
-
* Fetch the current epoch from the on-chain consortium config account
|
|
141
|
-
*
|
|
142
|
-
* Borsh layout of Consortium Config:
|
|
143
|
-
* discriminator: 8 bytes (offset 0)
|
|
144
|
-
* admin: 32 bytes (offset 8)
|
|
145
|
-
* pending_admin: 32 bytes (offset 40)
|
|
146
|
-
* current_epoch: 8 bytes (offset 72, u64 LE)
|
|
140
|
+
* Fetch the current epoch from the on-chain consortium config account
|
|
141
|
+
* using Anchor IDL-based deserialization.
|
|
147
142
|
*/
|
|
148
143
|
export async function fetchCurrentEpoch(
|
|
149
|
-
|
|
144
|
+
consortiumProgram: Program,
|
|
150
145
|
consortiumConfigPDA: PublicKey,
|
|
151
146
|
): Promise<BN> {
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
)
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
throw new Error(
|
|
163
|
-
`Consortium config data too short: expected >= ${MIN_SIZE} bytes, got ${accountInfo.data.length}`,
|
|
164
|
-
);
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
const epochLe = accountInfo.data.readBigUInt64LE(EPOCH_OFFSET);
|
|
168
|
-
return new BN(epochLe.toString());
|
|
147
|
+
// Anchor converts all IDL names to camelCase before building the namespace
|
|
148
|
+
// and decoding accounts, so field access uses camelCase keys.
|
|
149
|
+
const accountNs = consortiumProgram.account as unknown as Record<
|
|
150
|
+
string,
|
|
151
|
+
{ fetch: (address: PublicKey) => Promise<unknown> }
|
|
152
|
+
>;
|
|
153
|
+
const raw = (await accountNs.config.fetch(consortiumConfigPDA)) as {
|
|
154
|
+
currentEpoch: BN;
|
|
155
|
+
};
|
|
156
|
+
return raw.currentEpoch;
|
|
169
157
|
}
|
|
170
158
|
|
|
171
|
-
// ──
|
|
159
|
+
// ── fetchAssetRouterConfig ──
|
|
172
160
|
|
|
173
161
|
/**
|
|
174
|
-
*
|
|
175
|
-
* Equivalent to Go's `getPausedAndBasculeFromConfig(data)`.
|
|
162
|
+
* Fetch and deserialize Asset Router `Config` account via Anchor IDL.
|
|
176
163
|
*
|
|
177
|
-
*
|
|
178
|
-
*
|
|
179
|
-
*
|
|
180
|
-
*
|
|
181
|
-
*
|
|
182
|
-
*
|
|
183
|
-
* mailbox: Pubkey (offset 137, 32 bytes)
|
|
184
|
-
* bascule_enabled: bool (offset 169, 1 byte)
|
|
185
|
-
* bascule_program: Pubkey (offset 170, 32 bytes) <- not in IDL
|
|
186
|
-
* bascule_gmp_program:Pubkey (offset 202, 32 bytes) <- not in IDL
|
|
187
|
-
* ledger_lchain_id: [u8;32] (offset 234, 32 bytes)
|
|
188
|
-
* bitcoin_lchain_id: [u8;32] (offset 266, 32 bytes)
|
|
164
|
+
* IDL layout (fields used by SDK):
|
|
165
|
+
* paused: bool
|
|
166
|
+
* native_mint: pubkey
|
|
167
|
+
* bascule: Option<pubkey> (classic bascule for BTC.B)
|
|
168
|
+
* bascule_gmp: Option<pubkey> (bascule for LBTC GMP)
|
|
169
|
+
* ledger_lchain_id: [u8; 32]
|
|
189
170
|
*/
|
|
190
|
-
export function
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
:
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
return { paused, nativeMint, basculeProgramId, basculeGmpProgramId, ledgerChainId };
|
|
171
|
+
export async function fetchAssetRouterConfig(
|
|
172
|
+
assetRouterProgram: Program,
|
|
173
|
+
configPDA: PublicKey,
|
|
174
|
+
): Promise<AssetRouterConfig> {
|
|
175
|
+
// Anchor camelCases IDL names, so `native_mint` → `nativeMint`,
|
|
176
|
+
// `bascule_gmp` → `basculeGmp`, `ledger_lchain_id` → `ledgerLchainId`.
|
|
177
|
+
const accountNs = assetRouterProgram.account as unknown as Record<
|
|
178
|
+
string,
|
|
179
|
+
{ fetch: (address: PublicKey) => Promise<unknown> }
|
|
180
|
+
>;
|
|
181
|
+
const raw = (await accountNs.config.fetch(configPDA)) as {
|
|
182
|
+
paused: boolean;
|
|
183
|
+
nativeMint: PublicKey;
|
|
184
|
+
bascule: PublicKey | null;
|
|
185
|
+
basculeGmp: PublicKey | null;
|
|
186
|
+
ledgerLchainId: number[];
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
return {
|
|
190
|
+
paused: raw.paused,
|
|
191
|
+
nativeMint: raw.nativeMint,
|
|
192
|
+
basculeProgramId: raw.bascule ?? null,
|
|
193
|
+
basculeGmpProgramId: raw.basculeGmp ?? null,
|
|
194
|
+
ledgerChainId: new Uint8Array(raw.ledgerLchainId),
|
|
195
|
+
};
|
|
217
196
|
}
|
|
218
197
|
|
|
219
198
|
// ── Consortium session ──
|
|
@@ -255,7 +234,6 @@ export async function executeConsortiumSession(ctx: ClaimContext): Promise<void>
|
|
|
255
234
|
payer: provider.publicKey,
|
|
256
235
|
config: consortiumConfigPDA,
|
|
257
236
|
session: sessionPDA,
|
|
258
|
-
validatedPayload: validatedPayloadPDA,
|
|
259
237
|
systemProgram: SystemProgram.programId,
|
|
260
238
|
})
|
|
261
239
|
.transaction();
|
|
@@ -265,22 +243,52 @@ export async function executeConsortiumSession(ctx: ClaimContext): Promise<void>
|
|
|
265
243
|
connection,
|
|
266
244
|
provider,
|
|
267
245
|
debugLabel: 'Consortium create_session',
|
|
268
|
-
skipPreflight: params.skipPreflight ??
|
|
246
|
+
skipPreflight: params.skipPreflight ?? true,
|
|
269
247
|
});
|
|
270
248
|
debugLog('create_session completed');
|
|
271
249
|
} else {
|
|
272
250
|
debugLog('Session already exists, skipping create_session');
|
|
273
251
|
}
|
|
274
252
|
|
|
275
|
-
// Step 2: post_session_signatures
|
|
276
|
-
|
|
277
|
-
|
|
253
|
+
// Step 2: post_session_signatures.
|
|
254
|
+
// Session raw layout: discriminator(8) | signed: Vec<bool> (4 LE len + N bytes) | weight: u64 LE | trailing bytes.
|
|
255
|
+
// Manual parse: Anchor coder rejects extra trailing bytes that exist in the on-chain account.
|
|
278
256
|
let sessionSigned = false;
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
257
|
+
const freshSessionAccount = sessionAccount
|
|
258
|
+
? sessionAccount
|
|
259
|
+
: await connection.getAccountInfo(sessionPDA);
|
|
260
|
+
if (freshSessionAccount) {
|
|
261
|
+
try {
|
|
262
|
+
const data = freshSessionAccount.data;
|
|
263
|
+
if (data.length < 20) {
|
|
264
|
+
throw new Error(`session account too short: ${data.length}`);
|
|
265
|
+
}
|
|
266
|
+
const signedLen = data.readUInt32LE(8);
|
|
267
|
+
const weightOffset = 12 + signedLen;
|
|
268
|
+
if (data.length < weightOffset + 8) {
|
|
269
|
+
throw new Error(
|
|
270
|
+
`session data truncated: need ${weightOffset + 8}, got ${data.length}`,
|
|
271
|
+
);
|
|
272
|
+
}
|
|
273
|
+
const weight = data.readBigUInt64LE(weightOffset);
|
|
274
|
+
let signedCount = 0;
|
|
275
|
+
for (let i = 0; i < signedLen; i++) {
|
|
276
|
+
if (data[12 + i] !== 0) signedCount += 1;
|
|
277
|
+
}
|
|
278
|
+
sessionSigned = weight > 0n;
|
|
279
|
+
debugLog(
|
|
280
|
+
'Session weight:',
|
|
281
|
+
weight.toString(),
|
|
282
|
+
'signed count:',
|
|
283
|
+
signedCount,
|
|
284
|
+
'of',
|
|
285
|
+
signedLen,
|
|
286
|
+
);
|
|
287
|
+
} catch (err) {
|
|
288
|
+
debugLog(
|
|
289
|
+
'Failed to parse session for signature check:',
|
|
290
|
+
err instanceof Error ? err.message : String(err),
|
|
291
|
+
);
|
|
284
292
|
}
|
|
285
293
|
}
|
|
286
294
|
|
|
@@ -309,7 +317,7 @@ export async function executeConsortiumSession(ctx: ClaimContext): Promise<void>
|
|
|
309
317
|
connection,
|
|
310
318
|
provider,
|
|
311
319
|
debugLabel: 'Consortium post_session_signatures',
|
|
312
|
-
skipPreflight: params.skipPreflight ??
|
|
320
|
+
skipPreflight: params.skipPreflight ?? true,
|
|
313
321
|
});
|
|
314
322
|
debugLog('post_session_signatures completed');
|
|
315
323
|
} else {
|
|
@@ -334,7 +342,7 @@ export async function executeConsortiumSession(ctx: ClaimContext): Promise<void>
|
|
|
334
342
|
connection,
|
|
335
343
|
provider,
|
|
336
344
|
debugLabel: 'Consortium finalize_session',
|
|
337
|
-
skipPreflight: params.skipPreflight ??
|
|
345
|
+
skipPreflight: params.skipPreflight ?? true,
|
|
338
346
|
});
|
|
339
347
|
debugLog('finalize_session completed — ValidatedPayload created');
|
|
340
348
|
}
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
import { Env } from '@lombard.finance/sdk-common';
|
|
2
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
3
|
+
import { useState } from 'react';
|
|
4
|
+
|
|
5
|
+
import { envToNetwork, getConfig } from '../../const/getConfig';
|
|
6
|
+
import {
|
|
7
|
+
Button,
|
|
8
|
+
CodeBlock,
|
|
9
|
+
ConnectButton,
|
|
10
|
+
ErrorDisplay,
|
|
11
|
+
ResultDisplay,
|
|
12
|
+
SectionCard,
|
|
13
|
+
} from '../../stories/components';
|
|
14
|
+
import { functionType } from '../../stories/decorators/function-type';
|
|
15
|
+
import { useConnect } from '../../stories/hooks/useConnect';
|
|
16
|
+
import useQuery from '../../stories/hooks/useQuery';
|
|
17
|
+
import { deposit } from './deposit';
|
|
18
|
+
|
|
19
|
+
interface DepositStoryArgs {
|
|
20
|
+
environment: Env;
|
|
21
|
+
amount: string;
|
|
22
|
+
recipient: string;
|
|
23
|
+
sourceTokenMint: string;
|
|
24
|
+
toLchainId: string;
|
|
25
|
+
toTokenAddress: string;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export const StoryView = ({
|
|
29
|
+
environment,
|
|
30
|
+
amount,
|
|
31
|
+
recipient,
|
|
32
|
+
sourceTokenMint,
|
|
33
|
+
toLchainId,
|
|
34
|
+
toTokenAddress,
|
|
35
|
+
}: DepositStoryArgs) => {
|
|
36
|
+
const network = envToNetwork[environment];
|
|
37
|
+
const config = getConfig(environment);
|
|
38
|
+
const [transactionLogs, setTransactionLogs] = useState<string[] | null>(null);
|
|
39
|
+
|
|
40
|
+
const {
|
|
41
|
+
data: connectionData,
|
|
42
|
+
error: connectError,
|
|
43
|
+
isLoading: isConnecting,
|
|
44
|
+
connect,
|
|
45
|
+
disconnect,
|
|
46
|
+
} = useConnect();
|
|
47
|
+
const isConnected = !!connectionData;
|
|
48
|
+
const address = connectionData?.address;
|
|
49
|
+
const provider = connectionData?.provider;
|
|
50
|
+
|
|
51
|
+
const effectiveSource = sourceTokenMint || config.btcbTokenMint;
|
|
52
|
+
const effectiveToToken = toTokenAddress || config.lbtcTokenMint;
|
|
53
|
+
|
|
54
|
+
const request = async () => {
|
|
55
|
+
if (!provider || !address) throw new Error('Wallet not connected.');
|
|
56
|
+
if (!recipient)
|
|
57
|
+
throw new Error('Recipient address is required (set in args).');
|
|
58
|
+
const parsedAmount = parseFloat(amount);
|
|
59
|
+
if (!amount || isNaN(parsedAmount) || parsedAmount <= 0)
|
|
60
|
+
throw new Error('Amount must be a positive number in BTC (set in args).');
|
|
61
|
+
|
|
62
|
+
const amountSats = Math.round(parsedAmount * 1e8).toString();
|
|
63
|
+
|
|
64
|
+
setTransactionLogs(null);
|
|
65
|
+
try {
|
|
66
|
+
const result = await deposit(provider, {
|
|
67
|
+
amount: amountSats,
|
|
68
|
+
recipient,
|
|
69
|
+
sourceTokenMint: sourceTokenMint || undefined,
|
|
70
|
+
toLchainId: toLchainId || undefined,
|
|
71
|
+
toTokenAddress: toTokenAddress || undefined,
|
|
72
|
+
network,
|
|
73
|
+
env: environment,
|
|
74
|
+
debug: true,
|
|
75
|
+
});
|
|
76
|
+
return result;
|
|
77
|
+
} catch (err: unknown) {
|
|
78
|
+
if (err instanceof Error && err.message.includes('Debug logs:')) {
|
|
79
|
+
const parts = err.message.split('Debug logs:\n');
|
|
80
|
+
setTransactionLogs(parts[1]?.split('\n') || []);
|
|
81
|
+
}
|
|
82
|
+
throw err;
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
const {
|
|
87
|
+
data: txHash,
|
|
88
|
+
error,
|
|
89
|
+
isLoading,
|
|
90
|
+
refetch: handleDeposit,
|
|
91
|
+
} = useQuery(
|
|
92
|
+
request,
|
|
93
|
+
[
|
|
94
|
+
provider,
|
|
95
|
+
address,
|
|
96
|
+
amount,
|
|
97
|
+
recipient,
|
|
98
|
+
sourceTokenMint,
|
|
99
|
+
toLchainId,
|
|
100
|
+
toTokenAddress,
|
|
101
|
+
environment,
|
|
102
|
+
],
|
|
103
|
+
false,
|
|
104
|
+
);
|
|
105
|
+
|
|
106
|
+
return (
|
|
107
|
+
<>
|
|
108
|
+
<ConnectButton
|
|
109
|
+
connect={connect}
|
|
110
|
+
disconnect={disconnect}
|
|
111
|
+
isConnected={isConnected}
|
|
112
|
+
isLoading={isConnecting}
|
|
113
|
+
error={connectError}
|
|
114
|
+
walletName={connectionData?.walletName}
|
|
115
|
+
address={connectionData?.address}
|
|
116
|
+
network={network}
|
|
117
|
+
/>
|
|
118
|
+
|
|
119
|
+
{isConnected && (
|
|
120
|
+
<>
|
|
121
|
+
<SectionCard title="Configuration">
|
|
122
|
+
<p>
|
|
123
|
+
<strong>Environment:</strong> {environment}
|
|
124
|
+
</p>
|
|
125
|
+
<p>
|
|
126
|
+
<strong>Network:</strong> {network}
|
|
127
|
+
</p>
|
|
128
|
+
<p>
|
|
129
|
+
<strong>Amount:</strong> {amount} BTC
|
|
130
|
+
</p>
|
|
131
|
+
<p>
|
|
132
|
+
<strong>Recipient:</strong> {recipient || <em>Not set</em>}
|
|
133
|
+
</p>
|
|
134
|
+
<p>
|
|
135
|
+
<strong>Source token (e.g. BTC.b):</strong>{' '}
|
|
136
|
+
{effectiveSource || <em>Not configured</em>}
|
|
137
|
+
</p>
|
|
138
|
+
<p>
|
|
139
|
+
<strong>Destination token (e.g. LBTC):</strong>{' '}
|
|
140
|
+
{effectiveToToken || <em>Not configured</em>}
|
|
141
|
+
</p>
|
|
142
|
+
</SectionCard>
|
|
143
|
+
|
|
144
|
+
<div className="d-grid gap-2 my-4">
|
|
145
|
+
<Button
|
|
146
|
+
primary
|
|
147
|
+
size="large"
|
|
148
|
+
onClick={handleDeposit}
|
|
149
|
+
isLoading={isLoading}
|
|
150
|
+
actionName={deposit.name}
|
|
151
|
+
/>
|
|
152
|
+
</div>
|
|
153
|
+
|
|
154
|
+
{txHash && (
|
|
155
|
+
<ResultDisplay
|
|
156
|
+
result={txHash}
|
|
157
|
+
title="Deposit Transaction Hash"
|
|
158
|
+
successMessage="Success! Deposit (BTC.b → LBTC) transaction submitted."
|
|
159
|
+
/>
|
|
160
|
+
)}
|
|
161
|
+
{(error || connectError) && (
|
|
162
|
+
<ErrorDisplay
|
|
163
|
+
error={error || connectError}
|
|
164
|
+
title="Deposit Error"
|
|
165
|
+
/>
|
|
166
|
+
)}
|
|
167
|
+
|
|
168
|
+
{transactionLogs && transactionLogs.length > 0 && (
|
|
169
|
+
<SectionCard title="Transaction Logs (Debug)">
|
|
170
|
+
<CodeBlock text={transactionLogs.join('\n')} />
|
|
171
|
+
</SectionCard>
|
|
172
|
+
)}
|
|
173
|
+
</>
|
|
174
|
+
)}
|
|
175
|
+
</>
|
|
176
|
+
);
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
const meta: Meta<typeof StoryView> = {
|
|
180
|
+
title: 'write/deposit (Asset Router)',
|
|
181
|
+
component: StoryView,
|
|
182
|
+
tags: ['autodocs'],
|
|
183
|
+
decorators: [functionType('write')],
|
|
184
|
+
parameters: {
|
|
185
|
+
docs: {
|
|
186
|
+
description: {
|
|
187
|
+
component: `Demonstrates depositing source token (e.g. BTC.b) for destination token (e.g. LBTC) via the Asset Router's \`deposit\` instruction.
|
|
188
|
+
|
|
189
|
+
**Flow:**
|
|
190
|
+
1. Connect a Solana wallet holding the source token (default: BTC.b)
|
|
191
|
+
2. Enter the recipient address and amount (in BTC)
|
|
192
|
+
3. Optionally override source mint, destination chain ID, and destination token
|
|
193
|
+
4. Call \`deposit\` — burns the source token and sends a GMP message through the Mailbox
|
|
194
|
+
5. The destination token (e.g. LBTC) is minted to the recipient's ATA for that mint on the target chain (payload carries the token account address)
|
|
195
|
+
|
|
196
|
+
**Example (devnet):** PROGRAM_ID=LomVyJDZ91jeVbNnTupJXKJTQFakJVMc87CmwDHYt95, MAILBOX=LomJw912MoUd7iiAesTQAgz1paLcTqi6ndG3w3pnKH9`,
|
|
197
|
+
},
|
|
198
|
+
},
|
|
199
|
+
},
|
|
200
|
+
args: {
|
|
201
|
+
environment: Env.stage,
|
|
202
|
+
amount: '0.0002',
|
|
203
|
+
recipient: '',
|
|
204
|
+
sourceTokenMint: '',
|
|
205
|
+
toLchainId: '',
|
|
206
|
+
toTokenAddress: '',
|
|
207
|
+
},
|
|
208
|
+
argTypes: {
|
|
209
|
+
environment: {
|
|
210
|
+
control: { type: 'select' },
|
|
211
|
+
options: Object.values(Env),
|
|
212
|
+
},
|
|
213
|
+
amount: {
|
|
214
|
+
control: { type: 'text' },
|
|
215
|
+
description: 'Amount to deposit in BTC (e.g. 0.0002)',
|
|
216
|
+
},
|
|
217
|
+
recipient: {
|
|
218
|
+
control: { type: 'text' },
|
|
219
|
+
description:
|
|
220
|
+
'Recipient wallet (owner) for the destination token; SDK uses the associated token account in the deposit payload (Solana base58)',
|
|
221
|
+
},
|
|
222
|
+
sourceTokenMint: {
|
|
223
|
+
control: { type: 'text' },
|
|
224
|
+
description: 'Source token mint override (defaults to BTC.b from config)',
|
|
225
|
+
},
|
|
226
|
+
toLchainId: {
|
|
227
|
+
control: { type: 'text' },
|
|
228
|
+
description:
|
|
229
|
+
'Destination Lombard routing chain ID (hex). Defaults to Solana',
|
|
230
|
+
},
|
|
231
|
+
toTokenAddress: {
|
|
232
|
+
control: { type: 'text' },
|
|
233
|
+
description:
|
|
234
|
+
'Destination token mint override (defaults to LBTC from config)',
|
|
235
|
+
},
|
|
236
|
+
},
|
|
237
|
+
};
|
|
238
|
+
|
|
239
|
+
export default meta;
|
|
240
|
+
type Story = StoryObj<typeof meta>;
|