@chipi-stack/core 0.2.1

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 (53) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +91 -0
  3. package/dist/estimation/estimate-fee.d.ts +21 -0
  4. package/dist/estimation/estimate-fee.d.ts.map +1 -0
  5. package/dist/estimation/estimate-fee.js +34 -0
  6. package/dist/estimation/estimate-fee.js.map +1 -0
  7. package/dist/estimation/types.d.ts +14 -0
  8. package/dist/estimation/types.d.ts.map +1 -0
  9. package/dist/estimation/types.js +2 -0
  10. package/dist/estimation/types.js.map +1 -0
  11. package/dist/index.d.ts +12 -0
  12. package/dist/index.d.ts.map +1 -0
  13. package/dist/index.js +13 -0
  14. package/dist/index.js.map +1 -0
  15. package/dist/signers/direct-signer.d.ts +18 -0
  16. package/dist/signers/direct-signer.d.ts.map +1 -0
  17. package/dist/signers/direct-signer.js +32 -0
  18. package/dist/signers/direct-signer.js.map +1 -0
  19. package/dist/signers/external-signer.d.ts +17 -0
  20. package/dist/signers/external-signer.d.ts.map +1 -0
  21. package/dist/signers/external-signer.js +19 -0
  22. package/dist/signers/external-signer.js.map +1 -0
  23. package/dist/signers/passkey-signer.d.ts +25 -0
  24. package/dist/signers/passkey-signer.d.ts.map +1 -0
  25. package/dist/signers/passkey-signer.js +24 -0
  26. package/dist/signers/passkey-signer.js.map +1 -0
  27. package/dist/signers/types.d.ts +19 -0
  28. package/dist/signers/types.d.ts.map +1 -0
  29. package/dist/signers/types.js +2 -0
  30. package/dist/signers/types.js.map +1 -0
  31. package/dist/tokens/amount.d.ts +72 -0
  32. package/dist/tokens/amount.d.ts.map +1 -0
  33. package/dist/tokens/amount.js +166 -0
  34. package/dist/tokens/amount.js.map +1 -0
  35. package/dist/tokens/erc20.d.ts +38 -0
  36. package/dist/tokens/erc20.d.ts.map +1 -0
  37. package/dist/tokens/erc20.js +79 -0
  38. package/dist/tokens/erc20.js.map +1 -0
  39. package/dist/tokens/presets/mainnet.json +38 -0
  40. package/dist/tokens/presets/sepolia.json +20 -0
  41. package/dist/tokens/registry.d.ts +27 -0
  42. package/dist/tokens/registry.d.ts.map +1 -0
  43. package/dist/tokens/registry.js +38 -0
  44. package/dist/tokens/registry.js.map +1 -0
  45. package/dist/transactions/tx-builder.d.ts +56 -0
  46. package/dist/transactions/tx-builder.d.ts.map +1 -0
  47. package/dist/transactions/tx-builder.js +104 -0
  48. package/dist/transactions/tx-builder.js.map +1 -0
  49. package/dist/transactions/types.d.ts +11 -0
  50. package/dist/transactions/types.d.ts.map +1 -0
  51. package/dist/transactions/types.js +2 -0
  52. package/dist/transactions/types.js.map +1 -0
  53. package/package.json +41 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024-2026 Chipi Pay
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,91 @@
1
+ # @chipi-stack/core
2
+
3
+ Core primitives for Chipi Pay SDK: transaction building, token math, signer adapters, and fee estimation.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install @chipi-stack/core
9
+ ```
10
+
11
+ ## Modules
12
+
13
+ ### TxBuilder
14
+
15
+ Build Starknet multicall transactions with a fluent API:
16
+
17
+ ```typescript
18
+ import { TxBuilder } from "@chipi-stack/core";
19
+
20
+ const tx = TxBuilder.new()
21
+ .transfer({ token: "USDC", to: "0x...", amount: "10.00" })
22
+ .approve({ token: "USDC", spender: "0x...", amount: "50.00" })
23
+ .build();
24
+ ```
25
+
26
+ ### TokenRegistry
27
+
28
+ Look up token metadata (address, decimals) by symbol and network:
29
+
30
+ ```typescript
31
+ import { TokenRegistry } from "@chipi-stack/core";
32
+
33
+ const usdc = TokenRegistry.get("USDC", "mainnet");
34
+ // { address: "0x033068...", decimals: 6, symbol: "USDC" }
35
+ ```
36
+
37
+ ### Amount
38
+
39
+ Safe token amount math with decimal precision:
40
+
41
+ ```typescript
42
+ import { Amount } from "@chipi-stack/core";
43
+
44
+ const amt = Amount.fromHuman("10.50", 6); // 10.5 USDC
45
+ amt.toRaw(); // 10500000n
46
+ amt.toHuman(); // "10.50"
47
+ ```
48
+
49
+ ### Signers
50
+
51
+ Unified `SignerAdapter` interface with three implementations:
52
+
53
+ ```typescript
54
+ import { DirectSigner, ExternalSigner, PasskeySigner } from "@chipi-stack/core";
55
+
56
+ // Local key (testing only)
57
+ const direct = new DirectSigner("0x...");
58
+
59
+ // External provider (Privy, Cartridge, etc.)
60
+ const external = new ExternalSigner({
61
+ getPublicKey: () => provider.getPublicKey(),
62
+ sign: (hash) => provider.sign(hash),
63
+ getAccountAddress: () => provider.getAddress(),
64
+ });
65
+
66
+ // Passkey-based signer
67
+ const passkey = new PasskeySigner({
68
+ authenticateFn: (challenge) => passkeyAuth(challenge),
69
+ publicKey: "0x...",
70
+ accountAddress: "0x...",
71
+ });
72
+ ```
73
+
74
+ ### Fee Estimation
75
+
76
+ Estimate Starknet transaction fees before execution:
77
+
78
+ ```typescript
79
+ import { estimateFee, preflight } from "@chipi-stack/core";
80
+
81
+ const fee = await estimateFee(calls, account);
82
+ const check = await preflight(calls, account); // fee + balance check
83
+ ```
84
+
85
+ ## Documentation
86
+
87
+ Full docs at [docs.chipipay.com](https://docs.chipipay.com)
88
+
89
+ ## License
90
+
91
+ MIT
@@ -0,0 +1,21 @@
1
+ import type { Account, Call } from "starknet";
2
+ import type { FeeEstimate, PreflightResult } from "./types.js";
3
+ /**
4
+ * Estimate invocation fees for a set of calls.
5
+ * Does NOT execute the transaction.
6
+ *
7
+ * @param calls - Array of Starknet calls to estimate
8
+ * @param account - Starknet Account instance
9
+ * @throws If calls array is empty
10
+ */
11
+ export declare function estimateFee(calls: Call[], account: Account): Promise<FeeEstimate>;
12
+ /**
13
+ * Simulate a transaction without submitting it.
14
+ * Returns trace and fee estimation.
15
+ *
16
+ * @param calls - Array of Starknet calls to simulate
17
+ * @param account - Starknet Account instance
18
+ * @throws If calls array is empty
19
+ */
20
+ export declare function preflight(calls: Call[], account: Account): Promise<PreflightResult>;
21
+ //# sourceMappingURL=estimate-fee.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"estimate-fee.d.ts","sourceRoot":"","sources":["../../src/estimation/estimate-fee.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAC9C,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAE/D;;;;;;;GAOG;AACH,wBAAsB,WAAW,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,WAAW,CAAC,CAIvF;AAED;;;;;;;GAOG;AACH,wBAAsB,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,eAAe,CAAC,CASzF"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Estimate invocation fees for a set of calls.
3
+ * Does NOT execute the transaction.
4
+ *
5
+ * @param calls - Array of Starknet calls to estimate
6
+ * @param account - Starknet Account instance
7
+ * @throws If calls array is empty
8
+ */
9
+ export async function estimateFee(calls, account) {
10
+ if (calls.length === 0)
11
+ throw new Error("No calls to estimate");
12
+ const result = await account.estimateInvokeFee(calls);
13
+ return result;
14
+ }
15
+ /**
16
+ * Simulate a transaction without submitting it.
17
+ * Returns trace and fee estimation.
18
+ *
19
+ * @param calls - Array of Starknet calls to simulate
20
+ * @param account - Starknet Account instance
21
+ * @throws If calls array is empty
22
+ */
23
+ export async function preflight(calls, account) {
24
+ if (calls.length === 0)
25
+ throw new Error("No calls to preflight");
26
+ const result = await account.simulateTransaction([{ type: "INVOKE", payload: calls }], {
27
+ skipValidate: false,
28
+ });
29
+ if (!result || result.length === 0) {
30
+ throw new Error("Simulation returned no results");
31
+ }
32
+ return result[0];
33
+ }
34
+ //# sourceMappingURL=estimate-fee.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"estimate-fee.js","sourceRoot":"","sources":["../../src/estimation/estimate-fee.ts"],"names":[],"mappings":"AAGA;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,KAAa,EAAE,OAAgB;IAC/D,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;IAChE,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC;IACtD,OAAO,MAAgC,CAAC;AAC1C,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,KAAa,EAAE,OAAgB;IAC7D,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;IACjE,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,mBAAmB,CAAC,CAAC,EAAE,IAAI,EAAE,QAAiB,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE;QAC9F,YAAY,EAAE,KAAK;KACpB,CAAC,CAAC;IACH,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACnC,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;IACpD,CAAC;IACD,OAAO,MAAM,CAAC,CAAC,CAA+B,CAAC;AACjD,CAAC"}
@@ -0,0 +1,14 @@
1
+ export interface FeeEstimate {
2
+ overall_fee: bigint;
3
+ gas_consumed: bigint;
4
+ gas_price: bigint;
5
+ data_gas_consumed?: bigint;
6
+ data_gas_price?: bigint;
7
+ }
8
+ export interface PreflightResult {
9
+ transaction_trace: unknown;
10
+ fee_estimation: {
11
+ overall_fee: bigint;
12
+ };
13
+ }
14
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/estimation/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,WAAW;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,eAAe;IAC9B,iBAAiB,EAAE,OAAO,CAAC;IAC3B,cAAc,EAAE;QAAE,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC;CACzC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/estimation/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,12 @@
1
+ export { Amount, type TokenInfo } from "./tokens/amount.js";
2
+ export { Erc20 } from "./tokens/erc20.js";
3
+ export { TokenRegistry, type Network } from "./tokens/registry.js";
4
+ export { TxBuilder } from "./transactions/tx-builder.js";
5
+ export type { TransferTarget, PreflightResult } from "./transactions/types.js";
6
+ export { DirectSigner } from "./signers/direct-signer.js";
7
+ export { PasskeySigner } from "./signers/passkey-signer.js";
8
+ export { ExternalSigner } from "./signers/external-signer.js";
9
+ export type { SignerAdapter, SignResult } from "./signers/types.js";
10
+ export { estimateFee, preflight } from "./estimation/estimate-fee.js";
11
+ export type { FeeEstimate } from "./estimation/types.js";
12
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,KAAK,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,KAAK,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAGnE,OAAO,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AACzD,YAAY,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAG/E,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAGpE,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AACtE,YAAY,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,13 @@
1
+ // Tokens
2
+ export { Amount } from "./tokens/amount.js";
3
+ export { Erc20 } from "./tokens/erc20.js";
4
+ export { TokenRegistry } from "./tokens/registry.js";
5
+ // Transactions
6
+ export { TxBuilder } from "./transactions/tx-builder.js";
7
+ // Signers
8
+ export { DirectSigner } from "./signers/direct-signer.js";
9
+ export { PasskeySigner } from "./signers/passkey-signer.js";
10
+ export { ExternalSigner } from "./signers/external-signer.js";
11
+ // Estimation
12
+ export { estimateFee, preflight } from "./estimation/estimate-fee.js";
13
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,SAAS;AACT,OAAO,EAAE,MAAM,EAAkB,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAgB,MAAM,sBAAsB,CAAC;AAEnE,eAAe;AACf,OAAO,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAGzD,UAAU;AACV,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAG9D,aAAa;AACb,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC"}
@@ -0,0 +1,18 @@
1
+ import type { SignerAdapter, SignResult } from "./types.js";
2
+ /**
3
+ * Signer backed by a local private key.
4
+ * Equivalent to StarkZap's StarkSigner.
5
+ *
6
+ * WARNING: Only for development/testing.
7
+ * Never hardcode private keys in production.
8
+ */
9
+ export declare class DirectSigner implements SignerAdapter {
10
+ private readonly privateKey;
11
+ private readonly publicKey;
12
+ private readonly accountAddress;
13
+ constructor(privateKey: string, accountAddress?: string);
14
+ getPublicKey(): Promise<string>;
15
+ sign(messageHash: string): Promise<SignResult>;
16
+ getAccountAddress(): Promise<string>;
17
+ }
18
+ //# sourceMappingURL=direct-signer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"direct-signer.d.ts","sourceRoot":"","sources":["../../src/signers/direct-signer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE5D;;;;;;GAMG;AACH,qBAAa,YAAa,YAAW,aAAa;IAChD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;gBAE5B,UAAU,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,MAAM;IAWjD,YAAY,IAAI,OAAO,CAAC,MAAM,CAAC;IAI/B,IAAI,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAQ9C,iBAAiB,IAAI,OAAO,CAAC,MAAM,CAAC;CAG3C"}
@@ -0,0 +1,32 @@
1
+ import { ec, encode } from "starknet";
2
+ /**
3
+ * Signer backed by a local private key.
4
+ * Equivalent to StarkZap's StarkSigner.
5
+ *
6
+ * WARNING: Only for development/testing.
7
+ * Never hardcode private keys in production.
8
+ */
9
+ export class DirectSigner {
10
+ constructor(privateKey, accountAddress) {
11
+ if (!privateKey || !/^0x[0-9a-fA-F]+$/.test(privateKey)) {
12
+ throw new Error("Invalid private key: must be a hex string starting with 0x");
13
+ }
14
+ this.privateKey = privateKey;
15
+ this.publicKey = encode.addHexPrefix(encode.buf2hex(ec.starkCurve.getPublicKey(privateKey, true)));
16
+ this.accountAddress = accountAddress ?? this.publicKey;
17
+ }
18
+ async getPublicKey() {
19
+ return this.publicKey;
20
+ }
21
+ async sign(messageHash) {
22
+ const signature = ec.starkCurve.sign(messageHash, this.privateKey);
23
+ return {
24
+ r: encode.addHexPrefix(signature.r.toString(16)),
25
+ s: encode.addHexPrefix(signature.s.toString(16)),
26
+ };
27
+ }
28
+ async getAccountAddress() {
29
+ return this.accountAddress;
30
+ }
31
+ }
32
+ //# sourceMappingURL=direct-signer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"direct-signer.js","sourceRoot":"","sources":["../../src/signers/direct-signer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAGtC;;;;;;GAMG;AACH,MAAM,OAAO,YAAY;IAKvB,YAAY,UAAkB,EAAE,cAAuB;QACrD,IAAI,CAAC,UAAU,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;YACxD,MAAM,IAAI,KAAK,CAAC,4DAA4D,CAAC,CAAC;QAChF,CAAC;QACD,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QAC7B,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC,YAAY,CAClC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC,CAC7D,CAAC;QACF,IAAI,CAAC,cAAc,GAAG,cAAc,IAAI,IAAI,CAAC,SAAS,CAAC;IACzD,CAAC;IAED,KAAK,CAAC,YAAY;QAChB,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,WAAmB;QAC5B,MAAM,SAAS,GAAG,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;QACnE,OAAO;YACL,CAAC,EAAE,MAAM,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;YAChD,CAAC,EAAE,MAAM,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;SACjD,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,iBAAiB;QACrB,OAAO,IAAI,CAAC,cAAc,CAAC;IAC7B,CAAC;CACF"}
@@ -0,0 +1,17 @@
1
+ import type { SignerAdapter, SignResult } from "./types.js";
2
+ /**
3
+ * Adapter for external signer providers (Privy, Cartridge, etc.).
4
+ * Consumers provide the signing function — ExternalSigner just wraps the interface.
5
+ */
6
+ export declare class ExternalSigner implements SignerAdapter {
7
+ private readonly opts;
8
+ constructor(opts: {
9
+ getPublicKey: () => Promise<string>;
10
+ sign: (messageHash: string) => Promise<SignResult>;
11
+ getAccountAddress: () => Promise<string>;
12
+ });
13
+ getPublicKey(): Promise<string>;
14
+ sign(messageHash: string): Promise<SignResult>;
15
+ getAccountAddress(): Promise<string>;
16
+ }
17
+ //# sourceMappingURL=external-signer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"external-signer.d.ts","sourceRoot":"","sources":["../../src/signers/external-signer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE5D;;;GAGG;AACH,qBAAa,cAAe,YAAW,aAAa;IAClD,OAAO,CAAC,QAAQ,CAAC,IAAI,CAInB;gBAEU,IAAI,EAAE;QAChB,YAAY,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;QACpC,IAAI,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC;QACnD,iBAAiB,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;KAC1C;IAID,YAAY,IAAI,OAAO,CAAC,MAAM,CAAC;IAG/B,IAAI,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAG9C,iBAAiB,IAAI,OAAO,CAAC,MAAM,CAAC;CAGrC"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Adapter for external signer providers (Privy, Cartridge, etc.).
3
+ * Consumers provide the signing function — ExternalSigner just wraps the interface.
4
+ */
5
+ export class ExternalSigner {
6
+ constructor(opts) {
7
+ this.opts = opts;
8
+ }
9
+ getPublicKey() {
10
+ return this.opts.getPublicKey();
11
+ }
12
+ sign(messageHash) {
13
+ return this.opts.sign(messageHash);
14
+ }
15
+ getAccountAddress() {
16
+ return this.opts.getAccountAddress();
17
+ }
18
+ }
19
+ //# sourceMappingURL=external-signer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"external-signer.js","sourceRoot":"","sources":["../../src/signers/external-signer.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,OAAO,cAAc;IAOzB,YAAY,IAIX;QACC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;IAED,YAAY;QACV,OAAO,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;IAClC,CAAC;IACD,IAAI,CAAC,WAAmB;QACtB,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IACrC,CAAC;IACD,iBAAiB;QACf,OAAO,IAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE,CAAC;IACvC,CAAC;CACF"}
@@ -0,0 +1,25 @@
1
+ import type { SignerAdapter, SignResult } from "./types.js";
2
+ /**
3
+ * Signer that wraps @chipi-stack/passkey functions.
4
+ * Does NOT modify @chipi-stack/passkey — only wraps it.
5
+ *
6
+ * @param authenticateFn - The authenticatePasskey function from @chipi-stack/passkey
7
+ * @param publicKey - The passkey public key (obtained during registration)
8
+ */
9
+ export declare class PasskeySigner implements SignerAdapter {
10
+ private readonly authenticateFn;
11
+ private readonly pubKey;
12
+ private readonly accountAddress;
13
+ constructor(opts: {
14
+ authenticateFn: (challenge: string) => Promise<{
15
+ r: string;
16
+ s: string;
17
+ }>;
18
+ publicKey: string;
19
+ accountAddress: string;
20
+ });
21
+ getPublicKey(): Promise<string>;
22
+ sign(messageHash: string): Promise<SignResult>;
23
+ getAccountAddress(): Promise<string>;
24
+ }
25
+ //# sourceMappingURL=passkey-signer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"passkey-signer.d.ts","sourceRoot":"","sources":["../../src/signers/passkey-signer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE5D;;;;;;GAMG;AACH,qBAAa,aAAc,YAAW,aAAa;IACjD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAA2D;IAC1F,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;gBAE5B,IAAI,EAAE;QAChB,cAAc,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC;YAAE,CAAC,EAAE,MAAM,CAAC;YAAC,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;QACzE,SAAS,EAAE,MAAM,CAAC;QAClB,cAAc,EAAE,MAAM,CAAC;KACxB;IAMK,YAAY,IAAI,OAAO,CAAC,MAAM,CAAC;IAI/B,IAAI,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAI9C,iBAAiB,IAAI,OAAO,CAAC,MAAM,CAAC;CAG3C"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Signer that wraps @chipi-stack/passkey functions.
3
+ * Does NOT modify @chipi-stack/passkey — only wraps it.
4
+ *
5
+ * @param authenticateFn - The authenticatePasskey function from @chipi-stack/passkey
6
+ * @param publicKey - The passkey public key (obtained during registration)
7
+ */
8
+ export class PasskeySigner {
9
+ constructor(opts) {
10
+ this.authenticateFn = opts.authenticateFn;
11
+ this.pubKey = opts.publicKey;
12
+ this.accountAddress = opts.accountAddress;
13
+ }
14
+ async getPublicKey() {
15
+ return this.pubKey;
16
+ }
17
+ async sign(messageHash) {
18
+ return this.authenticateFn(messageHash);
19
+ }
20
+ async getAccountAddress() {
21
+ return this.accountAddress;
22
+ }
23
+ }
24
+ //# sourceMappingURL=passkey-signer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"passkey-signer.js","sourceRoot":"","sources":["../../src/signers/passkey-signer.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,MAAM,OAAO,aAAa;IAKxB,YAAY,IAIX;QACC,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,cAAc,CAAC;QAC1C,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC;QAC7B,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,cAAc,CAAC;IAC5C,CAAC;IAED,KAAK,CAAC,YAAY;QAChB,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,WAAmB;QAC5B,OAAO,IAAI,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC;IAC1C,CAAC;IAED,KAAK,CAAC,iBAAiB;QACrB,OAAO,IAAI,CAAC,cAAc,CAAC;IAC7B,CAAC;CACF"}
@@ -0,0 +1,19 @@
1
+ /** Result of a signing operation. */
2
+ export interface SignResult {
3
+ r: string;
4
+ s: string;
5
+ }
6
+ /**
7
+ * Unified signer interface.
8
+ * Implementations wrap different key management strategies
9
+ * (local key, passkey, external provider).
10
+ */
11
+ export interface SignerAdapter {
12
+ /** Get the public key associated with this signer. */
13
+ getPublicKey(): Promise<string>;
14
+ /** Sign a message hash. */
15
+ sign(messageHash: string): Promise<SignResult>;
16
+ /** Get the account address derived from this signer. */
17
+ getAccountAddress(): Promise<string>;
18
+ }
19
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/signers/types.ts"],"names":[],"mappings":"AAAA,qCAAqC;AACrC,MAAM,WAAW,UAAU;IACzB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACX;AAED;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B,sDAAsD;IACtD,YAAY,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAEhC,2BAA2B;IAC3B,IAAI,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IAE/C,wDAAwD;IACxD,iBAAiB,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;CACtC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/signers/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,72 @@
1
+ /** Minimal token info needed by Amount. */
2
+ export interface TokenInfo {
3
+ symbol: string;
4
+ decimals: number;
5
+ address: string;
6
+ }
7
+ /**
8
+ * Immutable representation of a token amount.
9
+ * Stores raw base units (e.g., wei for ETH, micro-units for USDC).
10
+ * All arithmetic is exact BigInt math — no floating point.
11
+ */
12
+ export declare class Amount {
13
+ /** Raw value in base units (smallest denomination). */
14
+ readonly raw: bigint;
15
+ /** Number of decimal places for this token. */
16
+ readonly decimals: number;
17
+ /** Token symbol (e.g., "USDC", "ETH"). */
18
+ readonly symbol: string;
19
+ private constructor();
20
+ private static assertValidDecimals;
21
+ /**
22
+ * Parse a human-readable string into an Amount.
23
+ * @param value - Human-readable value (e.g., "1.5")
24
+ * @param token - Token info with decimals and symbol
25
+ * @throws If value is negative, non-numeric, or has too many decimal places
26
+ */
27
+ static parse(value: string, token: TokenInfo): Amount;
28
+ /**
29
+ * Create an Amount from a raw bigint value (base units).
30
+ * @param raw - Raw value in base units
31
+ * @param decimals - Token decimal places
32
+ * @param symbol - Token symbol (defaults to "")
33
+ */
34
+ static fromRaw(raw: bigint, decimals: number, symbol?: string): Amount;
35
+ /** Add two amounts. Both must have the same decimals. */
36
+ add(other: Amount): Amount;
37
+ /**
38
+ * Subtract an amount.
39
+ * @throws If result would be negative
40
+ */
41
+ subtract(other: Amount): Amount;
42
+ /**
43
+ * Multiply by a scalar bigint.
44
+ * @throws If scalar is negative
45
+ */
46
+ multiply(scalar: bigint): Amount;
47
+ /**
48
+ * Divide by a scalar bigint. Truncates (no rounding).
49
+ * @throws If divisor is zero or negative
50
+ */
51
+ divide(divisor: bigint): Amount;
52
+ eq(other: Amount): boolean;
53
+ gt(other: Amount): boolean;
54
+ gte(other: Amount): boolean;
55
+ lt(other: Amount): boolean;
56
+ lte(other: Amount): boolean;
57
+ isZero(): boolean;
58
+ /** Returns the raw bigint value (base units). */
59
+ toBase(): bigint;
60
+ /**
61
+ * Returns human-readable string (e.g., "1.5").
62
+ * Trailing zeros after decimal are preserved to one place minimum.
63
+ */
64
+ toUnit(): string;
65
+ /**
66
+ * Returns formatted string with symbol (e.g., "1.5 USDC").
67
+ * @param compressed - If true, shorten large numbers (e.g., "1.5M USDC")
68
+ */
69
+ toFormatted(compressed?: boolean): string;
70
+ private assertSameDecimals;
71
+ }
72
+ //# sourceMappingURL=amount.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"amount.d.ts","sourceRoot":"","sources":["../../src/tokens/amount.ts"],"names":[],"mappings":"AAAA,2CAA2C;AAC3C,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;GAIG;AACH,qBAAa,MAAM;IACjB,uDAAuD;IACvD,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,+CAA+C;IAC/C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,0CAA0C;IAC1C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAExB,OAAO;IAMP,OAAO,CAAC,MAAM,CAAC,mBAAmB;IAQlC;;;;;OAKG;IACH,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,GAAG,MAAM;IAkBrD;;;;;OAKG;IACH,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,SAAK,GAAG,MAAM;IAQlE,yDAAyD;IACzD,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;IAK1B;;;OAGG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;IAQ/B;;;OAGG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;IAKhC;;;OAGG;IACH,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM;IAQ/B,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAI1B,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAI1B,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAI3B,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAI1B,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAI3B,MAAM,IAAI,OAAO;IAMjB,iDAAiD;IACjD,MAAM,IAAI,MAAM;IAIhB;;;OAGG;IACH,MAAM,IAAI,MAAM;IAYhB;;;OAGG;IACH,WAAW,CAAC,UAAU,UAAQ,GAAG,MAAM;IAwBvC,OAAO,CAAC,kBAAkB;CAY3B"}
@@ -0,0 +1,166 @@
1
+ /**
2
+ * Immutable representation of a token amount.
3
+ * Stores raw base units (e.g., wei for ETH, micro-units for USDC).
4
+ * All arithmetic is exact BigInt math — no floating point.
5
+ */
6
+ export class Amount {
7
+ constructor(raw, decimals, symbol) {
8
+ this.raw = raw;
9
+ this.decimals = decimals;
10
+ this.symbol = symbol;
11
+ }
12
+ static assertValidDecimals(decimals) {
13
+ if (!Number.isInteger(decimals) || decimals < 0) {
14
+ throw new Error("Token decimals must be a non-negative integer");
15
+ }
16
+ }
17
+ // ── Factory Methods ──────────────────────────────────────────
18
+ /**
19
+ * Parse a human-readable string into an Amount.
20
+ * @param value - Human-readable value (e.g., "1.5")
21
+ * @param token - Token info with decimals and symbol
22
+ * @throws If value is negative, non-numeric, or has too many decimal places
23
+ */
24
+ static parse(value, token) {
25
+ Amount.assertValidDecimals(token.decimals);
26
+ if (!/^\d+(\.\d+)?$/.test(value)) {
27
+ throw new Error(`Invalid amount: "${value}" — must be a non-negative number`);
28
+ }
29
+ const [whole, fraction = ""] = value.split(".");
30
+ if (fraction.length > token.decimals) {
31
+ throw new Error(`Too many decimal places: ${fraction.length} > ${token.decimals} for ${token.symbol}`);
32
+ }
33
+ const padded = fraction.padEnd(token.decimals, "0");
34
+ const raw = BigInt(whole + padded);
35
+ return new Amount(raw, token.decimals, token.symbol);
36
+ }
37
+ /**
38
+ * Create an Amount from a raw bigint value (base units).
39
+ * @param raw - Raw value in base units
40
+ * @param decimals - Token decimal places
41
+ * @param symbol - Token symbol (defaults to "")
42
+ */
43
+ static fromRaw(raw, decimals, symbol = "") {
44
+ if (raw < 0n)
45
+ throw new Error("Amount cannot be negative");
46
+ Amount.assertValidDecimals(decimals);
47
+ return new Amount(raw, decimals, symbol);
48
+ }
49
+ // ── Arithmetic ───────────────────────────────────────────────
50
+ /** Add two amounts. Both must have the same decimals. */
51
+ add(other) {
52
+ this.assertSameDecimals(other);
53
+ return new Amount(this.raw + other.raw, this.decimals, this.symbol);
54
+ }
55
+ /**
56
+ * Subtract an amount.
57
+ * @throws If result would be negative
58
+ */
59
+ subtract(other) {
60
+ this.assertSameDecimals(other);
61
+ if (this.raw < other.raw) {
62
+ throw new Error("Subtraction would result in negative amount");
63
+ }
64
+ return new Amount(this.raw - other.raw, this.decimals, this.symbol);
65
+ }
66
+ /**
67
+ * Multiply by a scalar bigint.
68
+ * @throws If scalar is negative
69
+ */
70
+ multiply(scalar) {
71
+ if (scalar < 0n)
72
+ throw new Error("Scalar cannot be negative");
73
+ return new Amount(this.raw * scalar, this.decimals, this.symbol);
74
+ }
75
+ /**
76
+ * Divide by a scalar bigint. Truncates (no rounding).
77
+ * @throws If divisor is zero or negative
78
+ */
79
+ divide(divisor) {
80
+ if (divisor === 0n)
81
+ throw new Error("Division by zero");
82
+ if (divisor < 0n)
83
+ throw new Error("Divisor cannot be negative");
84
+ return new Amount(this.raw / divisor, this.decimals, this.symbol);
85
+ }
86
+ // ── Comparisons ──────────────────────────────────────────────
87
+ eq(other) {
88
+ this.assertSameDecimals(other);
89
+ return this.raw === other.raw;
90
+ }
91
+ gt(other) {
92
+ this.assertSameDecimals(other);
93
+ return this.raw > other.raw;
94
+ }
95
+ gte(other) {
96
+ this.assertSameDecimals(other);
97
+ return this.raw >= other.raw;
98
+ }
99
+ lt(other) {
100
+ this.assertSameDecimals(other);
101
+ return this.raw < other.raw;
102
+ }
103
+ lte(other) {
104
+ this.assertSameDecimals(other);
105
+ return this.raw <= other.raw;
106
+ }
107
+ isZero() {
108
+ return this.raw === 0n;
109
+ }
110
+ // ── Formatting ───────────────────────────────────────────────
111
+ /** Returns the raw bigint value (base units). */
112
+ toBase() {
113
+ return this.raw;
114
+ }
115
+ /**
116
+ * Returns human-readable string (e.g., "1.5").
117
+ * Trailing zeros after decimal are preserved to one place minimum.
118
+ */
119
+ toUnit() {
120
+ const str = this.raw.toString().padStart(this.decimals + 1, "0");
121
+ const whole = str.slice(0, str.length - this.decimals) || "0";
122
+ const fraction = str.slice(str.length - this.decimals);
123
+ if (this.decimals === 0)
124
+ return whole;
125
+ // Trim trailing zeros but keep at least one decimal place
126
+ const trimmed = fraction.replace(/0+$/, "") || "0";
127
+ return `${whole}.${trimmed}`;
128
+ }
129
+ /**
130
+ * Returns formatted string with symbol (e.g., "1.5 USDC").
131
+ * @param compressed - If true, shorten large numbers (e.g., "1.5M USDC")
132
+ */
133
+ toFormatted(compressed = false) {
134
+ if (compressed) {
135
+ // Use BigInt arithmetic to avoid parseFloat precision loss
136
+ const scale = 10n ** BigInt(this.decimals);
137
+ const wholePart = this.raw / scale;
138
+ let display;
139
+ if (wholePart >= 1000000n) {
140
+ const major = wholePart / 1000000n;
141
+ const minor = (wholePart % 1000000n) / 100000n; // one decimal
142
+ display = `${major}.${minor}M`;
143
+ }
144
+ else if (wholePart >= 1000n) {
145
+ const major = wholePart / 1000n;
146
+ const minor = (wholePart % 1000n) / 100n; // one decimal
147
+ display = `${major}.${minor}K`;
148
+ }
149
+ else {
150
+ display = this.toUnit();
151
+ }
152
+ return this.symbol ? `${display} ${this.symbol}` : display;
153
+ }
154
+ return this.symbol ? `${this.toUnit()} ${this.symbol}` : this.toUnit();
155
+ }
156
+ // ── Internal ─────────────────────────────────────────────────
157
+ assertSameDecimals(other) {
158
+ if (this.decimals !== other.decimals) {
159
+ throw new Error(`Cannot operate on amounts with different decimals: ${this.decimals} vs ${other.decimals}`);
160
+ }
161
+ if (this.symbol && other.symbol && this.symbol !== other.symbol) {
162
+ throw new Error(`Cannot operate on amounts with different symbols: ${this.symbol} vs ${other.symbol}`);
163
+ }
164
+ }
165
+ }
166
+ //# sourceMappingURL=amount.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"amount.js","sourceRoot":"","sources":["../../src/tokens/amount.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ import type { Account, Call } from "starknet";
2
+ import { Amount, type TokenInfo } from "./amount.js";
3
+ /**
4
+ * Typed ERC20 contract wrapper.
5
+ * Generates Call objects for approve/transfer and queries for balance/allowance.
6
+ *
7
+ * @example
8
+ * const usdc = new Erc20({ symbol: 'USDC', decimals: 6, address: '0x...' }, account);
9
+ * const balance = await usdc.balanceOf(myAddress);
10
+ * console.log(balance.toFormatted()); // "150.5 USDC"
11
+ */
12
+ export declare class Erc20 {
13
+ private readonly token;
14
+ private readonly account;
15
+ constructor(token: TokenInfo, account: Account);
16
+ /**
17
+ * Query the balance of an address.
18
+ * @returns Amount representing the balance
19
+ */
20
+ balanceOf(address: string): Promise<Amount>;
21
+ /**
22
+ * Query the allowance of owner for spender.
23
+ * @returns Amount representing the allowance
24
+ */
25
+ allowance(owner: string, spender: string): Promise<Amount>;
26
+ /**
27
+ * Build an approve Call (does not execute).
28
+ * @returns Call object for use with TxBuilder or Account.execute()
29
+ */
30
+ approveCall(spender: string, amount: Amount): Call;
31
+ /**
32
+ * Build a transfer Call (does not execute).
33
+ * @returns Call object for use with TxBuilder or Account.execute()
34
+ */
35
+ transferCall(recipient: string, amount: Amount): Call;
36
+ private assertCompatibleAmount;
37
+ }
38
+ //# sourceMappingURL=erc20.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"erc20.d.ts","sourceRoot":"","sources":["../../src/tokens/erc20.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAE9C,OAAO,EAAE,MAAM,EAAE,KAAK,SAAS,EAAE,MAAM,aAAa,CAAC;AAErD;;;;;;;;GAQG;AACH,qBAAa,KAAK;IAChB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAY;IAClC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAU;gBAEtB,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO;IAK9C;;;OAGG;IACG,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAWjD;;;OAGG;IACG,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAUhE;;;OAGG;IACH,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAUlD;;;OAGG;IACH,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAUrD,OAAO,CAAC,sBAAsB;CAY/B"}
@@ -0,0 +1,79 @@
1
+ import { uint256 } from "starknet";
2
+ import { Amount } from "./amount.js";
3
+ /**
4
+ * Typed ERC20 contract wrapper.
5
+ * Generates Call objects for approve/transfer and queries for balance/allowance.
6
+ *
7
+ * @example
8
+ * const usdc = new Erc20({ symbol: 'USDC', decimals: 6, address: '0x...' }, account);
9
+ * const balance = await usdc.balanceOf(myAddress);
10
+ * console.log(balance.toFormatted()); // "150.5 USDC"
11
+ */
12
+ export class Erc20 {
13
+ constructor(token, account) {
14
+ this.token = token;
15
+ this.account = account;
16
+ }
17
+ /**
18
+ * Query the balance of an address.
19
+ * @returns Amount representing the balance
20
+ */
21
+ async balanceOf(address) {
22
+ const result = await this.account.callContract({
23
+ contractAddress: this.token.address,
24
+ entrypoint: "balanceOf",
25
+ calldata: [address],
26
+ });
27
+ // StarkNet returns uint256 as [low, high]
28
+ const raw = uint256.uint256ToBN({ low: result[0], high: result[1] });
29
+ return Amount.fromRaw(raw, this.token.decimals, this.token.symbol);
30
+ }
31
+ /**
32
+ * Query the allowance of owner for spender.
33
+ * @returns Amount representing the allowance
34
+ */
35
+ async allowance(owner, spender) {
36
+ const result = await this.account.callContract({
37
+ contractAddress: this.token.address,
38
+ entrypoint: "allowance",
39
+ calldata: [owner, spender],
40
+ });
41
+ const raw = uint256.uint256ToBN({ low: result[0], high: result[1] });
42
+ return Amount.fromRaw(raw, this.token.decimals, this.token.symbol);
43
+ }
44
+ /**
45
+ * Build an approve Call (does not execute).
46
+ * @returns Call object for use with TxBuilder or Account.execute()
47
+ */
48
+ approveCall(spender, amount) {
49
+ this.assertCompatibleAmount(amount);
50
+ const u256 = uint256.bnToUint256(amount.toBase());
51
+ return {
52
+ contractAddress: this.token.address,
53
+ entrypoint: "approve",
54
+ calldata: [spender, u256.low.toString(), u256.high.toString()],
55
+ };
56
+ }
57
+ /**
58
+ * Build a transfer Call (does not execute).
59
+ * @returns Call object for use with TxBuilder or Account.execute()
60
+ */
61
+ transferCall(recipient, amount) {
62
+ this.assertCompatibleAmount(amount);
63
+ const u256 = uint256.bnToUint256(amount.toBase());
64
+ return {
65
+ contractAddress: this.token.address,
66
+ entrypoint: "transfer",
67
+ calldata: [recipient, u256.low.toString(), u256.high.toString()],
68
+ };
69
+ }
70
+ assertCompatibleAmount(amount) {
71
+ if (amount.decimals !== this.token.decimals) {
72
+ throw new Error(`Amount decimals mismatch: expected ${this.token.decimals}, got ${amount.decimals}`);
73
+ }
74
+ if (amount.symbol && amount.symbol !== this.token.symbol) {
75
+ throw new Error(`Amount symbol mismatch: expected ${this.token.symbol}, got ${amount.symbol}`);
76
+ }
77
+ }
78
+ }
79
+ //# sourceMappingURL=erc20.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"erc20.js","sourceRoot":"","sources":["../../src/tokens/erc20.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ [
2
+ {
3
+ "symbol": "ETH",
4
+ "decimals": 18,
5
+ "address": "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7",
6
+ "name": "Ether"
7
+ },
8
+ {
9
+ "symbol": "USDC",
10
+ "decimals": 6,
11
+ "address": "0x033068f6539f8e6e6b131e6b2b814e6c34a5224bc66947c47dab9dfee93b35fb",
12
+ "name": "USD Coin"
13
+ },
14
+ {
15
+ "symbol": "USDT",
16
+ "decimals": 6,
17
+ "address": "0x068f5c6a61780768455de69077e07e89787839bf8166decfbf92b645209c0fb8",
18
+ "name": "Tether USD"
19
+ },
20
+ {
21
+ "symbol": "DAI",
22
+ "decimals": 18,
23
+ "address": "0x00da114221cb83fa859dbdb4c44beeaa0bb37c7537ad5ae66fe5e0efd20e6eb3",
24
+ "name": "Dai Stablecoin"
25
+ },
26
+ {
27
+ "symbol": "STRK",
28
+ "decimals": 18,
29
+ "address": "0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d",
30
+ "name": "Starknet Token"
31
+ },
32
+ {
33
+ "symbol": "WBTC",
34
+ "decimals": 8,
35
+ "address": "0x03fe2b97c1fd336e750087d68b9b867997fd64a2661ff3ca5a7c771641e8e7ac",
36
+ "name": "Wrapped Bitcoin"
37
+ }
38
+ ]
@@ -0,0 +1,20 @@
1
+ [
2
+ {
3
+ "symbol": "ETH",
4
+ "decimals": 18,
5
+ "address": "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7",
6
+ "name": "Ether"
7
+ },
8
+ {
9
+ "symbol": "USDC",
10
+ "decimals": 6,
11
+ "address": "0x005a643907b9a4bc6a55e9069c4fd5fd1f5c79a22470690f75556c4736e34426",
12
+ "name": "USD Coin (Testnet)"
13
+ },
14
+ {
15
+ "symbol": "STRK",
16
+ "decimals": 18,
17
+ "address": "0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d",
18
+ "name": "Starknet Token"
19
+ }
20
+ ]
@@ -0,0 +1,27 @@
1
+ import type { TokenInfo } from "./amount.js";
2
+ export type Network = "mainnet" | "sepolia";
3
+ interface TokenEntry extends TokenInfo {
4
+ name: string;
5
+ }
6
+ /**
7
+ * Registry for looking up token metadata by symbol or address.
8
+ *
9
+ * @example
10
+ * const registry = new TokenRegistry('mainnet');
11
+ * const usdc = registry.bySymbol('USDC');
12
+ * const amount = Amount.parse('10.0', usdc!);
13
+ */
14
+ export declare class TokenRegistry {
15
+ private readonly tokens;
16
+ private readonly bySymbolMap;
17
+ private readonly byAddressMap;
18
+ constructor(network: Network);
19
+ /** Find a token by its symbol (case-insensitive). */
20
+ bySymbol(symbol: string): TokenEntry | undefined;
21
+ /** Find a token by its contract address (case-insensitive). */
22
+ byAddress(address: string): TokenEntry | undefined;
23
+ /** List all tokens in this registry. */
24
+ all(): TokenEntry[];
25
+ }
26
+ export {};
27
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/tokens/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAI7C,MAAM,MAAM,OAAO,GAAG,SAAS,GAAG,SAAS,CAAC;AAE5C,UAAU,UAAW,SAAQ,SAAS;IACpC,IAAI,EAAE,MAAM,CAAC;CACd;AAOD;;;;;;;GAOG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAe;IACtC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA0B;IACtD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAA0B;gBAE3C,OAAO,EAAE,OAAO;IAU5B,qDAAqD;IACrD,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS;IAIhD,+DAA+D;IAC/D,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS;IAIlD,wCAAwC;IACxC,GAAG,IAAI,UAAU,EAAE;CAGpB"}
@@ -0,0 +1,38 @@
1
+ import mainnetTokens from "./presets/mainnet.json" with { type: "json" };
2
+ import sepoliaTokens from "./presets/sepolia.json" with { type: "json" };
3
+ const PRESETS = {
4
+ mainnet: mainnetTokens,
5
+ sepolia: sepoliaTokens,
6
+ };
7
+ /**
8
+ * Registry for looking up token metadata by symbol or address.
9
+ *
10
+ * @example
11
+ * const registry = new TokenRegistry('mainnet');
12
+ * const usdc = registry.bySymbol('USDC');
13
+ * const amount = Amount.parse('10.0', usdc!);
14
+ */
15
+ export class TokenRegistry {
16
+ constructor(network) {
17
+ const preset = PRESETS[network];
18
+ if (!preset) {
19
+ throw new Error(`Invalid network: "${network}". Must be "mainnet" or "sepolia".`);
20
+ }
21
+ this.tokens = preset;
22
+ this.bySymbolMap = new Map(preset.map((t) => [t.symbol.toUpperCase(), t]));
23
+ this.byAddressMap = new Map(preset.map((t) => [t.address.toLowerCase(), t]));
24
+ }
25
+ /** Find a token by its symbol (case-insensitive). */
26
+ bySymbol(symbol) {
27
+ return this.bySymbolMap.get(symbol.toUpperCase());
28
+ }
29
+ /** Find a token by its contract address (case-insensitive). */
30
+ byAddress(address) {
31
+ return this.byAddressMap.get(address.toLowerCase());
32
+ }
33
+ /** List all tokens in this registry. */
34
+ all() {
35
+ return [...this.tokens];
36
+ }
37
+ }
38
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/tokens/registry.ts"],"names":[],"mappings":"AACA,OAAO,aAAa,MAAM,wBAAwB,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AACzE,OAAO,aAAa,MAAM,wBAAwB,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AAQzE,MAAM,OAAO,GAAkC;IAC7C,OAAO,EAAE,aAA6B;IACtC,OAAO,EAAE,aAA6B;CACvC,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,OAAO,aAAa;IAKxB,YAAY,OAAgB;QAC1B,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;QAChC,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CAAC,qBAAqB,OAAO,oCAAoC,CAAC,CAAC;QACpF,CAAC;QACD,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,WAAW,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAC3E,IAAI,CAAC,YAAY,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/E,CAAC;IAED,qDAAqD;IACrD,QAAQ,CAAC,MAAc;QACrB,OAAO,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC;IACpD,CAAC;IAED,+DAA+D;IAC/D,SAAS,CAAC,OAAe;QACvB,OAAO,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;IACtD,CAAC;IAED,wCAAwC;IACxC,GAAG;QACD,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC;IAC1B,CAAC;CACF"}
@@ -0,0 +1,56 @@
1
+ import type { Account, Call, InvokeFunctionResponse, EstimateFeeResponseOverhead } from "starknet";
2
+ import type { TransferTarget, PreflightResult } from "./types.js";
3
+ /**
4
+ * Fluent builder for batching Starknet calls.
5
+ * All calls execute atomically via Account.execute().
6
+ *
7
+ * @example
8
+ * const result = await new TxBuilder(account)
9
+ * .approve(tokenAddr, spenderAddr, amount)
10
+ * .transfer(tokenAddr, [{ to: recipient, amount: 1000n }])
11
+ * .send();
12
+ */
13
+ export declare class TxBuilder {
14
+ private readonly account;
15
+ private readonly _calls;
16
+ private sent;
17
+ constructor(account: Account);
18
+ /** Returns a copy of the current call batch. */
19
+ calls(): Call[];
20
+ /**
21
+ * Add one or more raw calls.
22
+ * @param call - A single Call or array of Calls
23
+ */
24
+ add(call: Call | Call[]): this;
25
+ /**
26
+ * Add an ERC20 approve call.
27
+ * @param token - Token contract address
28
+ * @param spender - Address to approve
29
+ * @param amount - Raw amount in base units
30
+ */
31
+ approve(token: string, spender: string, amount: bigint): this;
32
+ /**
33
+ * Add one or more ERC20 transfer calls.
34
+ * @param token - Token contract address
35
+ * @param targets - Array of { to, amount } pairs
36
+ */
37
+ transfer(token: string, targets: TransferTarget[]): this;
38
+ /**
39
+ * Execute all batched calls atomically.
40
+ * @throws If no calls have been added
41
+ * @throws If send() was already called
42
+ */
43
+ send(): Promise<InvokeFunctionResponse>;
44
+ /**
45
+ * Estimate fees for the current batch without executing.
46
+ * @throws If no calls have been added
47
+ */
48
+ estimateFee(): Promise<EstimateFeeResponseOverhead>;
49
+ /**
50
+ * Simulate the transaction without submitting to the network.
51
+ * Useful for checking if a transaction would succeed.
52
+ * @throws If no calls have been added
53
+ */
54
+ preflight(): Promise<PreflightResult>;
55
+ }
56
+ //# sourceMappingURL=tx-builder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tx-builder.d.ts","sourceRoot":"","sources":["../../src/transactions/tx-builder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,sBAAsB,EAAE,2BAA2B,EAAE,MAAM,UAAU,CAAC;AAEnG,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElE;;;;;;;;;GASG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAU;IAClC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAc;IACrC,OAAO,CAAC,IAAI,CAAS;gBAET,OAAO,EAAE,OAAO;IAI5B,gDAAgD;IAChD,KAAK,IAAI,IAAI,EAAE;IAIf;;;OAGG;IACH,GAAG,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,EAAE,GAAG,IAAI;IAM9B;;;;;OAKG;IACH,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAW7D;;;;OAIG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,EAAE,GAAG,IAAI;IAaxD;;;;OAIG;IACG,IAAI,IAAI,OAAO,CAAC,sBAAsB,CAAC;IAQ7C;;;OAGG;IACG,WAAW,IAAI,OAAO,CAAC,2BAA2B,CAAC;IAKzD;;;;OAIG;IACG,SAAS,IAAI,OAAO,CAAC,eAAe,CAAC;CAW5C"}
@@ -0,0 +1,104 @@
1
+ import { uint256 } from "starknet";
2
+ /**
3
+ * Fluent builder for batching Starknet calls.
4
+ * All calls execute atomically via Account.execute().
5
+ *
6
+ * @example
7
+ * const result = await new TxBuilder(account)
8
+ * .approve(tokenAddr, spenderAddr, amount)
9
+ * .transfer(tokenAddr, [{ to: recipient, amount: 1000n }])
10
+ * .send();
11
+ */
12
+ export class TxBuilder {
13
+ constructor(account) {
14
+ this._calls = [];
15
+ this.sent = false;
16
+ this.account = account;
17
+ }
18
+ /** Returns a copy of the current call batch. */
19
+ calls() {
20
+ return [...this._calls];
21
+ }
22
+ /**
23
+ * Add one or more raw calls.
24
+ * @param call - A single Call or array of Calls
25
+ */
26
+ add(call) {
27
+ const toAdd = Array.isArray(call) ? call : [call];
28
+ this._calls.push(...toAdd);
29
+ return this;
30
+ }
31
+ /**
32
+ * Add an ERC20 approve call.
33
+ * @param token - Token contract address
34
+ * @param spender - Address to approve
35
+ * @param amount - Raw amount in base units
36
+ */
37
+ approve(token, spender, amount) {
38
+ if (amount < 0n)
39
+ throw new RangeError("Approve amount cannot be negative");
40
+ const u256 = uint256.bnToUint256(amount);
41
+ this._calls.push({
42
+ contractAddress: token,
43
+ entrypoint: "approve",
44
+ calldata: [spender, u256.low.toString(), u256.high.toString()],
45
+ });
46
+ return this;
47
+ }
48
+ /**
49
+ * Add one or more ERC20 transfer calls.
50
+ * @param token - Token contract address
51
+ * @param targets - Array of { to, amount } pairs
52
+ */
53
+ transfer(token, targets) {
54
+ for (const { to, amount } of targets) {
55
+ if (amount < 0n)
56
+ throw new RangeError("Transfer amount cannot be negative");
57
+ const u256 = uint256.bnToUint256(amount);
58
+ this._calls.push({
59
+ contractAddress: token,
60
+ entrypoint: "transfer",
61
+ calldata: [to, u256.low.toString(), u256.high.toString()],
62
+ });
63
+ }
64
+ return this;
65
+ }
66
+ /**
67
+ * Execute all batched calls atomically.
68
+ * @throws If no calls have been added
69
+ * @throws If send() was already called
70
+ */
71
+ async send() {
72
+ if (this.sent)
73
+ throw new Error("TxBuilder already sent — create a new builder");
74
+ if (this._calls.length === 0)
75
+ throw new Error("No calls to execute");
76
+ this.sent = true;
77
+ const calls = [...this._calls];
78
+ return this.account.execute(calls);
79
+ }
80
+ /**
81
+ * Estimate fees for the current batch without executing.
82
+ * @throws If no calls have been added
83
+ */
84
+ async estimateFee() {
85
+ if (this._calls.length === 0)
86
+ throw new Error("No calls to estimate");
87
+ return this.account.estimateInvokeFee([...this._calls]);
88
+ }
89
+ /**
90
+ * Simulate the transaction without submitting to the network.
91
+ * Useful for checking if a transaction would succeed.
92
+ * @throws If no calls have been added
93
+ */
94
+ async preflight() {
95
+ if (this._calls.length === 0)
96
+ throw new Error("No calls to preflight");
97
+ const result = await this.account.simulateTransaction([{ type: "INVOKE", payload: [...this._calls] }], { skipValidate: false });
98
+ if (!result || result.length === 0) {
99
+ throw new Error("Simulation returned no results");
100
+ }
101
+ return result[0];
102
+ }
103
+ }
104
+ //# sourceMappingURL=tx-builder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tx-builder.js","sourceRoot":"","sources":["../../src/transactions/tx-builder.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ export interface TransferTarget {
2
+ to: string;
3
+ amount: bigint;
4
+ }
5
+ export interface PreflightResult {
6
+ transaction_trace: unknown;
7
+ fee_estimation: {
8
+ overall_fee: bigint;
9
+ };
10
+ }
11
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/transactions/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,eAAe;IAC9B,iBAAiB,EAAE,OAAO,CAAC;IAC3B,cAAc,EAAE;QAAE,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC;CACzC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/transactions/types.ts"],"names":[],"mappings":""}
package/package.json ADDED
@@ -0,0 +1,41 @@
1
+ {
2
+ "name": "@chipi-stack/core",
3
+ "version": "0.2.1",
4
+ "description": "Core primitives for Chipi Pay SDK: TxBuilder, Amount, SignerAdapter, TokenRegistry",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "import": "./dist/index.js",
11
+ "types": "./dist/index.d.ts"
12
+ }
13
+ },
14
+ "files": [
15
+ "dist"
16
+ ],
17
+ "dependencies": {
18
+ "@chipi-stack/types": "^14.0.0"
19
+ },
20
+ "devDependencies": {
21
+ "typescript": "^5.7.3",
22
+ "vitest": "^3.2.4",
23
+ "starknet": ">=6.23.1"
24
+ },
25
+ "peerDependencies": {
26
+ "starknet": ">=6.23.1"
27
+ },
28
+ "engines": {
29
+ "node": ">=18.17.0"
30
+ },
31
+ "publishConfig": {
32
+ "access": "public"
33
+ },
34
+ "license": "MIT",
35
+ "scripts": {
36
+ "build": "tsc",
37
+ "test": "vitest run",
38
+ "test:watch": "vitest",
39
+ "typecheck": "tsc --noEmit"
40
+ }
41
+ }