@lombard.finance/sdk-starknet 0.3.0-canary.2

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.
Files changed (58) hide show
  1. package/README.md +128 -0
  2. package/dist/index.cjs +2 -0
  3. package/dist/index.cjs.map +1 -0
  4. package/dist/index.js +20 -0
  5. package/dist/index.js.map +1 -0
  6. package/dist/index2.cjs +229 -0
  7. package/dist/index2.cjs.map +1 -0
  8. package/dist/index2.js +30378 -0
  9. package/dist/index2.js.map +1 -0
  10. package/dist/index3.cjs +2 -0
  11. package/dist/index3.cjs.map +1 -0
  12. package/dist/index3.js +2316 -0
  13. package/dist/index3.js.map +1 -0
  14. package/package.json +66 -0
  15. package/src/contract-functions/approve.stories.tsx +74 -0
  16. package/src/contract-functions/approve.ts +56 -0
  17. package/src/contract-functions/balance-of.stories.tsx +54 -0
  18. package/src/contract-functions/balance-of.ts +41 -0
  19. package/src/contract-functions/mint.ts +109 -0
  20. package/src/contract-functions/redeem.ts +107 -0
  21. package/src/index.ts +25 -0
  22. package/src/module/createStarknetModule.ts +38 -0
  23. package/src/services/StarknetServiceImpl.ts +83 -0
  24. package/src/services/index.ts +7 -0
  25. package/src/stories/components/Button/Button.css +10 -0
  26. package/src/stories/components/Button/Button.tsx +52 -0
  27. package/src/stories/components/Button/index.ts +1 -0
  28. package/src/stories/components/CodeBlock/CodeBlock.tsx +38 -0
  29. package/src/stories/components/CodeBlock/CodeBlockStyles.css +3 -0
  30. package/src/stories/components/CodeBlock/index.ts +1 -0
  31. package/src/stories/components/ConnectButton/connect-button.tsx +112 -0
  32. package/src/stories/components/ConnectButton/index.ts +1 -0
  33. package/src/stories/components/Spinner/Spinner.tsx +24 -0
  34. package/src/stories/components/Spinner/index.ts +1 -0
  35. package/src/stories/components/decorators/function-type.tsx +66 -0
  36. package/src/stories/components/decorators/index.ts +1 -0
  37. package/src/stories/components/decorators/starknet-context.tsx +21 -0
  38. package/src/stories/components/error-block.tsx +21 -0
  39. package/src/stories/hooks/use-connection.ts +70 -0
  40. package/src/stories/hooks/use-query.ts +56 -0
  41. package/src/tokens/abi/ERC20_ABI.ts +1122 -0
  42. package/src/tokens/abi/LBTC_ABI.ts +1615 -0
  43. package/src/tokens/abi/LBTC_BASCULE_ABI.ts +709 -0
  44. package/src/tokens/abi/LBTC_BRIDGE_ABI.ts +1568 -0
  45. package/src/tokens/lib/tokens.ts +267 -0
  46. package/src/utils/account.ts +81 -0
  47. package/src/utils/chains.ts +33 -0
  48. package/src/utils/common.ts +11 -0
  49. package/src/utils/env.ts +6 -0
  50. package/src/utils/err.ts +121 -0
  51. package/src/utils/rpc-providers.ts +25 -0
  52. package/src/utils/signature.ts +60 -0
  53. package/src/utils/span.ts +56 -0
  54. package/src/utils/typed-data.ts +36 -0
  55. package/src/utils/wallet-account.ts +9 -0
  56. package/src/wallet-functions/sign-message.stories.tsx +72 -0
  57. package/src/wallet-functions/sign-message.ts +127 -0
  58. package/src/wallet-functions/sign-terms-of-service.ts +45 -0
@@ -0,0 +1,9 @@
1
+ import { WalletAccount } from 'starknet';
2
+
3
+ export type WalletAccountParameters = {
4
+ /** The starknet wallet account object */
5
+ walletAccount: WalletAccount;
6
+ };
7
+
8
+ /** Known wallets */
9
+ export type WalletName = 'Braavos' | 'Argent X' | 'Keplr' | 'OKX Wallet';
@@ -0,0 +1,72 @@
1
+ import type { Meta, StoryObj } from '@storybook/react';
2
+ import { useEffect } from 'react';
3
+
4
+ import { Button } from '../stories/components/Button';
5
+ import { CodeBlock } from '../stories/components/CodeBlock';
6
+ import { ConnectButton } from '../stories/components/ConnectButton';
7
+ import { functionType } from '../stories/components/decorators';
8
+ import { starknetContext } from '../stories/components/decorators/starknet-context';
9
+ import { useConnection } from '../stories/hooks/use-connection';
10
+ import useQuery from '../stories/hooks/use-query';
11
+ import { makeDestinationChainId,StarknetChainId } from '../utils/chains';
12
+ import { signMessage } from './sign-message';
13
+
14
+ const meta = {
15
+ title: 'write/sign-message',
16
+ component: StoryView,
17
+ tags: ['autodocs'],
18
+ decorators: [functionType('write'), starknetContext()],
19
+ } satisfies Meta<typeof StoryView>;
20
+
21
+ export default meta;
22
+
23
+ type Story = StoryObj<typeof meta>;
24
+
25
+ export const WithParams: Story = {
26
+ args: {
27
+ message: `destination chain id is ${makeDestinationChainId(StarknetChainId.SN_SEPOLIA)}`,
28
+ chainId: StarknetChainId.SN_SEPOLIA,
29
+ },
30
+ };
31
+
32
+ type FuncParameters = Parameters<typeof signMessage>[0];
33
+ type Props = Omit<FuncParameters, 'walletAccount'>;
34
+
35
+ export function StoryView(props: Props) {
36
+ const { account } = useConnection();
37
+
38
+ useEffect(() => {
39
+ console.log('s account', account);
40
+ }, [account]);
41
+
42
+ const request = async () => {
43
+ if (!account) {
44
+ console.info('Cannot perform action');
45
+ return;
46
+ }
47
+
48
+ return signMessage({
49
+ walletAccount: account,
50
+ ...props,
51
+ });
52
+ };
53
+
54
+ const { data, error, isLoading, refetch } = useQuery(request, [], false);
55
+
56
+ return (
57
+ <>
58
+ <div className="mb-4">
59
+ <ConnectButton desiredChainId={props.chainId} />
60
+ </div>
61
+
62
+ <Button
63
+ onClick={refetch}
64
+ disabled={isLoading}
65
+ isLoading={isLoading}
66
+ actionName={signMessage.name}
67
+ />
68
+
69
+ <CodeBlock text={error || data} />
70
+ </>
71
+ );
72
+ }
@@ -0,0 +1,127 @@
1
+ import { ec, Signature, typedData, WalletAccount } from 'starknet';
2
+
3
+ import { getPublicKey, recoverFullPublicKeys } from '../utils/account';
4
+ import {
5
+ ChainParameters,
6
+ makeDestinationChainId,
7
+ StarknetChainId,
8
+ } from '../utils/chains';
9
+ import { Address } from '../utils/common';
10
+ import { getRpcProvider } from '../utils/rpc-providers';
11
+ import { normalizeSignature } from '../utils/signature';
12
+ import { SIGN_MESSAGE_TYPED_DATA } from '../utils/typed-data';
13
+ import { WalletName } from '../utils/wallet-account';
14
+
15
+ type SignMessageParameters = {
16
+ message: string;
17
+ walletAccount: WalletAccount;
18
+ } & ChainParameters;
19
+
20
+ type SignMessageResult = {
21
+ /** The signing account address */
22
+ account: string;
23
+ /** The message hash */
24
+ hash: string;
25
+ /** The raw signature */
26
+ signature: Signature;
27
+ /** The signature (compact hex format) or Ethereum signature hex string */
28
+ signatureHex: string;
29
+ /** The signing account pubkey */
30
+ pubKey: string;
31
+ typedData: unknown;
32
+ /** A flag indicating whether the signature was verified on-chain */
33
+ verifiedOnChain: boolean;
34
+ verifiedOffChain:
35
+ | {
36
+ /** Recovered full pubkey */
37
+ fullPubKey: string;
38
+ /** A flag indicating whether the signature was verified off-chain */
39
+ verified: boolean;
40
+ }[]
41
+ | undefined;
42
+ };
43
+
44
+ export async function signMessage({
45
+ message,
46
+ walletAccount,
47
+ chainId = StarknetChainId.SN_MAIN,
48
+ }: SignMessageParameters): Promise<SignMessageResult> {
49
+ const personalMessageTypedData = SIGN_MESSAGE_TYPED_DATA(chainId, message);
50
+ const skipVerify = process.env.SKIP_STARKNET_VERIFY === 'true';
51
+
52
+ if (walletAccount.walletProvider.name.toLowerCase().includes('kelpr')) {
53
+ console.warn('Keplr wallet is not fully supported.');
54
+ }
55
+
56
+ const hashMsg = await walletAccount.hashMessage(personalMessageTypedData);
57
+ const signature = await walletAccount.signMessage(personalMessageTypedData);
58
+
59
+ // Use SDK's RPC provider for read-only operations to avoid wallet RPC rate limits
60
+ // (Wallet extensions like Braavos/ArgentX use OnFinality which has strict rate limits)
61
+ const rpcProvider = getRpcProvider(chainId);
62
+ const pubKey = await getPublicKey(
63
+ walletAccount.address as Address,
64
+ rpcProvider,
65
+ );
66
+
67
+ let verifiedOnChain = false;
68
+ if (!skipVerify) {
69
+ const provider = getRpcProvider(chainId);
70
+ verifiedOnChain = await provider.verifyMessageInStarknet(
71
+ hashMsg,
72
+ signature,
73
+ walletAccount.address,
74
+ );
75
+ }
76
+
77
+ const rs = normalizeSignature(
78
+ signature,
79
+ walletAccount.walletProvider.name as WalletName,
80
+ );
81
+
82
+ let verifiedOffChain = undefined;
83
+
84
+ if (rs instanceof ec.starkCurve.Signature) {
85
+ const fullPubKeys = recoverFullPublicKeys(rs, hashMsg);
86
+
87
+ verifiedOffChain = fullPubKeys.map(fpk => {
88
+ return {
89
+ fullPubKey: fpk,
90
+ verified: typedData.verifyMessage(hashMsg, rs, fpk),
91
+ };
92
+ });
93
+
94
+ const tfpk = verifiedOffChain.find(x =>
95
+ x.fullPubKey.includes(pubKey.slice(2)),
96
+ );
97
+ if (tfpk) verifiedOffChain = [tfpk];
98
+ }
99
+
100
+ return {
101
+ hash: hashMsg,
102
+ typedData: personalMessageTypedData,
103
+ signature,
104
+ signatureHex:
105
+ rs instanceof ec.starkCurve.Signature ? `0x${rs.toCompactHex()}` : rs,
106
+ account: `0x${walletAccount.address.slice(2).padStart(64, '0')}`,
107
+ pubKey,
108
+ verifiedOnChain,
109
+ verifiedOffChain,
110
+ };
111
+ }
112
+
113
+ type SignLbtcDestinationAddrStarknetParameters = Omit<
114
+ SignMessageParameters,
115
+ 'message'
116
+ >;
117
+
118
+ export async function signLbtcDestinationAddrStarknet({
119
+ walletAccount,
120
+ chainId = StarknetChainId.SN_MAIN,
121
+ }: SignLbtcDestinationAddrStarknetParameters) {
122
+ return signMessage({
123
+ walletAccount,
124
+ chainId,
125
+ message: `destination chain id is ${makeDestinationChainId(chainId)}`,
126
+ });
127
+ }
@@ -0,0 +1,45 @@
1
+ import { WalletAccount } from 'starknet';
2
+
3
+ import { ChainParameters, StarknetChainId } from '../utils/chains';
4
+ import { signMessage } from './sign-message';
5
+
6
+ const SIGN_MESSAGE =
7
+ 'I have read and agreed to the terms of service: https://docs.lombard.finance/legals/terms-of-service';
8
+
9
+ interface SignTermsOfServiceParams extends ChainParameters {
10
+ walletAccount: WalletAccount;
11
+ }
12
+
13
+ /**
14
+ * Signs terms of service for Starknet.
15
+ *
16
+ * @param {SignTermsOfServiceParams} params - Parameters including wallet account and chain ID
17
+ * @returns {Promise<{ signature: string; signatureHex: string; account: string; pubKey: string }>} The signature details
18
+ */
19
+ export async function signTermsOfService({
20
+ walletAccount,
21
+ chainId = StarknetChainId.SN_MAIN,
22
+ }: SignTermsOfServiceParams): Promise<{
23
+ signature: string;
24
+ signatureHex: string;
25
+ account: string;
26
+ pubKey: string;
27
+ }> {
28
+ const result = await signMessage({
29
+ message: SIGN_MESSAGE,
30
+ walletAccount,
31
+ chainId,
32
+ });
33
+
34
+ // Convert signature array to string format expected by backend
35
+ const signatureString = Array.isArray(result.signature)
36
+ ? JSON.stringify(result.signature)
37
+ : result.signature.toString();
38
+
39
+ return {
40
+ signature: signatureString,
41
+ signatureHex: result.signatureHex,
42
+ account: result.account,
43
+ pubKey: result.pubKey,
44
+ };
45
+ }