@droplinked_inc/web3-kit 0.1.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/dist/tokens.js ADDED
@@ -0,0 +1,215 @@
1
+ /**
2
+ * Hard-coded registry of vetted token contract addresses per chain.
3
+ *
4
+ * The single most important defence in this package: when a caller
5
+ * (e.g. a checkout component) says "the user is paying in USDC on
6
+ * Polygon", the address used in the on-chain call MUST come from this
7
+ * table — never from a backend response, never from a URL parameter,
8
+ * never from local storage. Every address has been cross-checked
9
+ * against the chain's canonical block explorer and the issuer's
10
+ * authoritative documentation.
11
+ *
12
+ * If a caller supplies their own address for a known symbol via
13
+ * `assertCanonicalTokenAddress`, the address is compared (case-
14
+ * insensitive) against the registry and rejected on mismatch with
15
+ * `TokenAddressMismatchError`. This blocks the "passing a malicious
16
+ * token addr that mimics USDC" class of supply-chain attacks.
17
+ */
18
+ import { Chains, Network } from './types.js';
19
+ import { TokenAddressMismatchError, UnknownTokenError, } from './errors.js';
20
+ import { deepFreeze } from './deep-freeze.js';
21
+ const lower = (s) => s.toLowerCase();
22
+ /**
23
+ * The frozen registry. Entries here are the authoritative truth.
24
+ *
25
+ * Sources:
26
+ * - USDC: Circle's canonical contract list (circle.com / developers.circle.com)
27
+ * - USDT: Tether's published contracts (tether.to/transparency)
28
+ * - DAI: MakerDAO's canonical deployments
29
+ * - WETH: chain-native wrappers from each ecosystem's docs
30
+ */
31
+ export const TOKEN_REGISTRY = deepFreeze({
32
+ [Chains.ETH]: {
33
+ [Network.MAINNET]: Object.freeze({
34
+ USDC: {
35
+ symbol: 'USDC',
36
+ name: 'USD Coin',
37
+ decimals: 6,
38
+ address: lower('0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48'),
39
+ },
40
+ USDT: {
41
+ symbol: 'USDT',
42
+ name: 'Tether USD',
43
+ decimals: 6,
44
+ address: lower('0xdAC17F958D2ee523a2206206994597C13D831ec7'),
45
+ },
46
+ DAI: {
47
+ symbol: 'DAI',
48
+ name: 'Dai Stablecoin',
49
+ decimals: 18,
50
+ address: lower('0x6B175474E89094C44Da98b954EedeAC495271d0F'),
51
+ },
52
+ WETH: {
53
+ symbol: 'WETH',
54
+ name: 'Wrapped Ether',
55
+ decimals: 18,
56
+ address: lower('0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2'),
57
+ },
58
+ }),
59
+ },
60
+ [Chains.POLYGON]: {
61
+ [Network.MAINNET]: Object.freeze({
62
+ USDC: {
63
+ symbol: 'USDC',
64
+ name: 'USD Coin',
65
+ decimals: 6,
66
+ address: lower('0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359'),
67
+ },
68
+ USDT: {
69
+ symbol: 'USDT',
70
+ name: 'Tether USD',
71
+ decimals: 6,
72
+ address: lower('0xc2132D05D31c914a87C6611C10748AEb04B58e8F'),
73
+ },
74
+ DAI: {
75
+ symbol: 'DAI',
76
+ name: 'Dai Stablecoin',
77
+ decimals: 18,
78
+ address: lower('0x8f3Cf7ad23Cd3CaDbD9735AFf958023239c6A063'),
79
+ },
80
+ WETH: {
81
+ symbol: 'WETH',
82
+ name: 'Wrapped Ether',
83
+ decimals: 18,
84
+ address: lower('0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619'),
85
+ },
86
+ }),
87
+ },
88
+ [Chains.BINANCE]: {
89
+ [Network.MAINNET]: Object.freeze({
90
+ USDC: {
91
+ symbol: 'USDC',
92
+ name: 'Binance-Peg USD Coin',
93
+ decimals: 18,
94
+ address: lower('0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d'),
95
+ },
96
+ USDT: {
97
+ symbol: 'USDT',
98
+ name: 'Binance-Peg Tether USD',
99
+ decimals: 18,
100
+ address: lower('0x55d398326f99059fF775485246999027B3197955'),
101
+ },
102
+ DAI: {
103
+ symbol: 'DAI',
104
+ name: 'Binance-Peg Dai',
105
+ decimals: 18,
106
+ address: lower('0x1AF3F329e8BE154074D8769D1FFa4eE058B1DBc3'),
107
+ },
108
+ }),
109
+ },
110
+ [Chains.BASE]: {
111
+ [Network.MAINNET]: Object.freeze({
112
+ USDC: {
113
+ symbol: 'USDC',
114
+ name: 'USD Coin',
115
+ decimals: 6,
116
+ address: lower('0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913'),
117
+ },
118
+ WETH: {
119
+ symbol: 'WETH',
120
+ name: 'Wrapped Ether',
121
+ decimals: 18,
122
+ address: lower('0x4200000000000000000000000000000000000006'),
123
+ },
124
+ }),
125
+ },
126
+ [Chains.LINEA]: {
127
+ [Network.MAINNET]: Object.freeze({
128
+ USDC: {
129
+ symbol: 'USDC',
130
+ name: 'USD Coin',
131
+ decimals: 6,
132
+ address: lower('0x176211869cA2b568f2A7D4EE941E073a821EE1ff'),
133
+ },
134
+ WETH: {
135
+ symbol: 'WETH',
136
+ name: 'Wrapped Ether',
137
+ decimals: 18,
138
+ address: lower('0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f'),
139
+ },
140
+ }),
141
+ },
142
+ [Chains.SKALE]: {
143
+ [Network.MAINNET]: Object.freeze({
144
+ USDC: {
145
+ symbol: 'USDC',
146
+ name: 'SKALE USD Coin',
147
+ decimals: 6,
148
+ address: lower('0x7Cf76E740Cb23b99337b21F392F22c47Ad910c67'),
149
+ },
150
+ }),
151
+ [Network.TESTNET]: Object.freeze({
152
+ USDC: {
153
+ symbol: 'USDC',
154
+ name: 'SKALE USD Coin (Testnet)',
155
+ decimals: 6,
156
+ address: lower('0x2aebcdc4f9F9149A50422FfF86198cB0939EA165'),
157
+ },
158
+ }),
159
+ },
160
+ [Chains.REDBELLY]: {},
161
+ [Chains.BITLAYER]: {},
162
+ [Chains.SOLANA]: {},
163
+ [Chains.XION]: {},
164
+ [Chains.UNSTOPPABLE]: {},
165
+ });
166
+ export function getTokenInfo(chain, network, symbol) {
167
+ const upperSymbol = symbol.toUpperCase();
168
+ const chainEntry = TOKEN_REGISTRY[chain];
169
+ const netEntry = chainEntry[network];
170
+ const token = netEntry?.[upperSymbol];
171
+ if (!token) {
172
+ throw new UnknownTokenError(chain, upperSymbol);
173
+ }
174
+ return token;
175
+ }
176
+ export function hasToken(chain, network, symbol) {
177
+ try {
178
+ getTokenInfo(chain, network, symbol);
179
+ return true;
180
+ }
181
+ catch {
182
+ return false;
183
+ }
184
+ }
185
+ export function listTokens(chain, network) {
186
+ const chainEntry = TOKEN_REGISTRY[chain];
187
+ const netEntry = chainEntry[network];
188
+ return netEntry ? Object.freeze(Object.values(netEntry)) : [];
189
+ }
190
+ /**
191
+ * If `claimedAddress` is provided, assert it matches the canonical
192
+ * registry value for `symbol` on the given (chain, network). On match,
193
+ * returns the canonical `TokenInfo`. On mismatch — even of one nibble
194
+ * — throws `TokenAddressMismatchError`.
195
+ *
196
+ * If `claimedAddress` is omitted, returns the canonical entry.
197
+ *
198
+ * This is the primary call-site for blocking the "look-alike USDC
199
+ * drainer" class of attacks: a malicious backend cannot persuade the
200
+ * checkout to send funds to its address by claiming "this is USDC".
201
+ */
202
+ export function assertCanonicalTokenAddress(args) {
203
+ const canonical = getTokenInfo(args.chain, args.network, args.symbol);
204
+ if (args.claimedAddress !== undefined) {
205
+ if (!/^0[xX][a-fA-F0-9]{40}$/u.test(args.claimedAddress)) {
206
+ throw new TokenAddressMismatchError(args.chain, args.symbol, canonical.address, args.claimedAddress);
207
+ }
208
+ const claimedLower = args.claimedAddress.toLowerCase();
209
+ if (claimedLower !== canonical.address) {
210
+ throw new TokenAddressMismatchError(args.chain, args.symbol, canonical.address, claimedLower);
211
+ }
212
+ }
213
+ return canonical;
214
+ }
215
+ //# sourceMappingURL=tokens.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tokens.js","sourceRoot":"","sources":["../src/tokens.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,EAAE,MAAM,EAAE,OAAO,EAAmB,MAAM,YAAY,CAAC;AAC9D,OAAO,EACL,yBAAyB,EACzB,iBAAiB,GAClB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAe9C,MAAM,KAAK,GAAG,CAAC,CAAS,EAAc,EAAE,CAAC,CAAC,CAAC,WAAW,EAAgB,CAAC;AAEvE;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,cAAc,GAAkB,UAAU,CAAC;IACtD,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE;QACZ,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC;YAC/B,IAAI,EAAE;gBACJ,MAAM,EAAE,MAAM;gBACd,IAAI,EAAE,UAAU;gBAChB,QAAQ,EAAE,CAAC;gBACX,OAAO,EAAE,KAAK,CAAC,4CAA4C,CAAC;aAC7D;YACD,IAAI,EAAE;gBACJ,MAAM,EAAE,MAAM;gBACd,IAAI,EAAE,YAAY;gBAClB,QAAQ,EAAE,CAAC;gBACX,OAAO,EAAE,KAAK,CAAC,4CAA4C,CAAC;aAC7D;YACD,GAAG,EAAE;gBACH,MAAM,EAAE,KAAK;gBACb,IAAI,EAAE,gBAAgB;gBACtB,QAAQ,EAAE,EAAE;gBACZ,OAAO,EAAE,KAAK,CAAC,4CAA4C,CAAC;aAC7D;YACD,IAAI,EAAE;gBACJ,MAAM,EAAE,MAAM;gBACd,IAAI,EAAE,eAAe;gBACrB,QAAQ,EAAE,EAAE;gBACZ,OAAO,EAAE,KAAK,CAAC,4CAA4C,CAAC;aAC7D;SACF,CAAC;KACH;IACD,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE;QAChB,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC;YAC/B,IAAI,EAAE;gBACJ,MAAM,EAAE,MAAM;gBACd,IAAI,EAAE,UAAU;gBAChB,QAAQ,EAAE,CAAC;gBACX,OAAO,EAAE,KAAK,CAAC,4CAA4C,CAAC;aAC7D;YACD,IAAI,EAAE;gBACJ,MAAM,EAAE,MAAM;gBACd,IAAI,EAAE,YAAY;gBAClB,QAAQ,EAAE,CAAC;gBACX,OAAO,EAAE,KAAK,CAAC,4CAA4C,CAAC;aAC7D;YACD,GAAG,EAAE;gBACH,MAAM,EAAE,KAAK;gBACb,IAAI,EAAE,gBAAgB;gBACtB,QAAQ,EAAE,EAAE;gBACZ,OAAO,EAAE,KAAK,CAAC,4CAA4C,CAAC;aAC7D;YACD,IAAI,EAAE;gBACJ,MAAM,EAAE,MAAM;gBACd,IAAI,EAAE,eAAe;gBACrB,QAAQ,EAAE,EAAE;gBACZ,OAAO,EAAE,KAAK,CAAC,4CAA4C,CAAC;aAC7D;SACF,CAAC;KACH;IACD,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE;QAChB,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC;YAC/B,IAAI,EAAE;gBACJ,MAAM,EAAE,MAAM;gBACd,IAAI,EAAE,sBAAsB;gBAC5B,QAAQ,EAAE,EAAE;gBACZ,OAAO,EAAE,KAAK,CAAC,4CAA4C,CAAC;aAC7D;YACD,IAAI,EAAE;gBACJ,MAAM,EAAE,MAAM;gBACd,IAAI,EAAE,wBAAwB;gBAC9B,QAAQ,EAAE,EAAE;gBACZ,OAAO,EAAE,KAAK,CAAC,4CAA4C,CAAC;aAC7D;YACD,GAAG,EAAE;gBACH,MAAM,EAAE,KAAK;gBACb,IAAI,EAAE,iBAAiB;gBACvB,QAAQ,EAAE,EAAE;gBACZ,OAAO,EAAE,KAAK,CAAC,4CAA4C,CAAC;aAC7D;SACF,CAAC;KACH;IACD,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE;QACb,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC;YAC/B,IAAI,EAAE;gBACJ,MAAM,EAAE,MAAM;gBACd,IAAI,EAAE,UAAU;gBAChB,QAAQ,EAAE,CAAC;gBACX,OAAO,EAAE,KAAK,CAAC,4CAA4C,CAAC;aAC7D;YACD,IAAI,EAAE;gBACJ,MAAM,EAAE,MAAM;gBACd,IAAI,EAAE,eAAe;gBACrB,QAAQ,EAAE,EAAE;gBACZ,OAAO,EAAE,KAAK,CAAC,4CAA4C,CAAC;aAC7D;SACF,CAAC;KACH;IACD,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;QACd,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC;YAC/B,IAAI,EAAE;gBACJ,MAAM,EAAE,MAAM;gBACd,IAAI,EAAE,UAAU;gBAChB,QAAQ,EAAE,CAAC;gBACX,OAAO,EAAE,KAAK,CAAC,4CAA4C,CAAC;aAC7D;YACD,IAAI,EAAE;gBACJ,MAAM,EAAE,MAAM;gBACd,IAAI,EAAE,eAAe;gBACrB,QAAQ,EAAE,EAAE;gBACZ,OAAO,EAAE,KAAK,CAAC,4CAA4C,CAAC;aAC7D;SACF,CAAC;KACH;IACD,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;QACd,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC;YAC/B,IAAI,EAAE;gBACJ,MAAM,EAAE,MAAM;gBACd,IAAI,EAAE,gBAAgB;gBACtB,QAAQ,EAAE,CAAC;gBACX,OAAO,EAAE,KAAK,CAAC,4CAA4C,CAAC;aAC7D;SACF,CAAC;QACF,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC;YAC/B,IAAI,EAAE;gBACJ,MAAM,EAAE,MAAM;gBACd,IAAI,EAAE,0BAA0B;gBAChC,QAAQ,EAAE,CAAC;gBACX,OAAO,EAAE,KAAK,CAAC,4CAA4C,CAAC;aAC7D;SACF,CAAC;KACH;IACD,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,EAAE;IACrB,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,EAAE;IACrB,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE;IACnB,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE;IACjB,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,EAAE;CACzB,CAAC,CAAC;AAEH,MAAM,UAAU,YAAY,CAC1B,KAAa,EACb,OAAgB,EAChB,MAAc;IAEd,MAAM,WAAW,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC;IACzC,MAAM,UAAU,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;IACzC,MAAM,QAAQ,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC;IACrC,MAAM,KAAK,GAAG,QAAQ,EAAE,CAAC,WAAW,CAAC,CAAC;IACtC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,iBAAiB,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;IAClD,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,QAAQ,CACtB,KAAa,EACb,OAAgB,EAChB,MAAc;IAEd,IAAI,CAAC;QACH,YAAY,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;QACrC,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,MAAM,UAAU,UAAU,CACxB,KAAa,EACb,OAAgB;IAEhB,MAAM,UAAU,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;IACzC,MAAM,QAAQ,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC;IACrC,OAAO,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AAChE,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,2BAA2B,CAAC,IAK3C;IACC,MAAM,SAAS,GAAG,YAAY,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IACtE,IAAI,IAAI,CAAC,cAAc,KAAK,SAAS,EAAE,CAAC;QACtC,IAAI,CAAC,yBAAyB,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC;YACzD,MAAM,IAAI,yBAAyB,CACjC,IAAI,CAAC,KAAK,EACV,IAAI,CAAC,MAAM,EACX,SAAS,CAAC,OAAO,EACjB,IAAI,CAAC,cAAc,CACpB,CAAC;QACJ,CAAC;QACD,MAAM,YAAY,GAAG,IAAI,CAAC,cAAc,CAAC,WAAW,EAAE,CAAC;QACvD,IAAI,YAAY,KAAK,SAAS,CAAC,OAAO,EAAE,CAAC;YACvC,MAAM,IAAI,yBAAyB,CACjC,IAAI,CAAC,KAAK,EACV,IAAI,CAAC,MAAM,EACX,SAAS,CAAC,OAAO,EACjB,YAAY,CACb,CAAC;QACJ,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC"}
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Transaction-payload builders.
3
+ *
4
+ * These functions only construct well-formed `bigint`-typed call-data
5
+ * and EIP-712 typed-data structures. They do NOT broadcast anything
6
+ * and they do NOT touch a wallet — that is the responsibility of
7
+ * the `@droplinked_inc/wallet-connection` connector.
8
+ *
9
+ * Every input is validated through `chains.ts` / `tokens.ts` so an
10
+ * attacker cannot smuggle in a hostile chainId, token address, or
11
+ * amount via a query string or backend response.
12
+ */
13
+ import { type Hex } from 'viem';
14
+ import { Chains, Network, type EvmAddress } from './types.js';
15
+ export interface Erc20TransferArgs {
16
+ chain: Chains;
17
+ network: Network;
18
+ /** Canonical symbol — "USDC", "USDT", … — looked up in the registry. */
19
+ tokenSymbol: string;
20
+ /** Optional caller-supplied address. If present, must match the registry. */
21
+ claimedTokenAddress?: string;
22
+ to: string;
23
+ amount: bigint | string | number;
24
+ }
25
+ export interface BuiltCall {
26
+ readonly to: EvmAddress;
27
+ readonly data: Hex;
28
+ readonly value: bigint;
29
+ readonly chainIdNumber: number;
30
+ }
31
+ /**
32
+ * Build an ERC-20 `transfer(address,uint256)` call. Returns the
33
+ * verified token-contract `to` address and ABI-encoded `data`.
34
+ */
35
+ export declare function buildErc20Transfer(args: Erc20TransferArgs): BuiltCall;
36
+ /**
37
+ * Build an ERC-20 `approve(spender,uint256)` call.
38
+ *
39
+ * Hardening note: a 0 amount IS allowed here, because the safe
40
+ * approve-twice pattern (`approve(spender, 0)` followed by
41
+ * `approve(spender, N)`) is the only way to defeat the front-run
42
+ * race on legacy USDT-like contracts.
43
+ */
44
+ export declare function buildErc20Approve(args: {
45
+ chain: Chains;
46
+ network: Network;
47
+ tokenSymbol: string;
48
+ claimedTokenAddress?: string;
49
+ spender: string;
50
+ amount: bigint | string | number;
51
+ }): BuiltCall;
52
+ export interface Eip712Domain {
53
+ readonly name: string;
54
+ readonly version: string;
55
+ readonly chainId: number;
56
+ readonly verifyingContract: EvmAddress;
57
+ }
58
+ /**
59
+ * Build an EIP-712 domain object pinned to a specific chain from the
60
+ * registry. The caller cannot smuggle a bogus chainId — it is derived
61
+ * from the (chain, network) pair, not user input.
62
+ */
63
+ export declare function buildEip712Domain(args: {
64
+ chain: Chains;
65
+ network: Network;
66
+ name: string;
67
+ version: string;
68
+ verifyingContract: string;
69
+ }): Eip712Domain;
70
+ export declare function buildNativeTransfer(args: {
71
+ chain: Chains;
72
+ network: Network;
73
+ to: string;
74
+ amount: bigint | string | number;
75
+ }): BuiltCall;
76
+ //# sourceMappingURL=tx-builder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tx-builder.d.ts","sourceRoot":"","sources":["../src/tx-builder.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAAgC,KAAK,GAAG,EAAE,MAAM,MAAM,CAAC;AAC9D,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,UAAU,EAAmC,MAAM,YAAY,CAAC;AAO/F,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;IACjB,wEAAwE;IACxE,WAAW,EAAE,MAAM,CAAC;IACpB,6EAA6E;IAC7E,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;CAClC;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,EAAE,EAAE,UAAU,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,GAAG,CAAC;IACnB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;CAChC;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,iBAAiB,GAAG,SAAS,CA6BrE;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE;IACtC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;CAClC,GAAG,SAAS,CAyBZ;AAID,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,iBAAiB,EAAE,UAAU,CAAC;CACxC;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE;IACtC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,iBAAiB,EAAE,MAAM,CAAC;CAC3B,GAAG,YAAY,CAcf;AAID,wBAAgB,mBAAmB,CAAC,IAAI,EAAE;IACxC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;CAClC,GAAG,SAAS,CAaZ"}
@@ -0,0 +1,116 @@
1
+ /**
2
+ * Transaction-payload builders.
3
+ *
4
+ * These functions only construct well-formed `bigint`-typed call-data
5
+ * and EIP-712 typed-data structures. They do NOT broadcast anything
6
+ * and they do NOT touch a wallet — that is the responsibility of
7
+ * the `@droplinked_inc/wallet-connection` connector.
8
+ *
9
+ * Every input is validated through `chains.ts` / `tokens.ts` so an
10
+ * attacker cannot smuggle in a hostile chainId, token address, or
11
+ * amount via a query string or backend response.
12
+ */
13
+ import { encodeFunctionData, erc20Abi } from 'viem';
14
+ import { EvmAddressSchema, Uint256Schema } from './types.js';
15
+ import { getChainDetails } from './chains.js';
16
+ import { assertCanonicalTokenAddress } from './tokens.js';
17
+ import { InvalidParametersException } from './errors.js';
18
+ /**
19
+ * Build an ERC-20 `transfer(address,uint256)` call. Returns the
20
+ * verified token-contract `to` address and ABI-encoded `data`.
21
+ */
22
+ export function buildErc20Transfer(args) {
23
+ const details = getChainDetails(args.chain, args.network);
24
+ const token = assertCanonicalTokenAddress({
25
+ chain: args.chain,
26
+ network: args.network,
27
+ symbol: args.tokenSymbol,
28
+ ...(args.claimedTokenAddress !== undefined
29
+ ? { claimedAddress: args.claimedTokenAddress }
30
+ : {}),
31
+ });
32
+ const recipient = EvmAddressSchema.parse(args.to);
33
+ const amount = Uint256Schema.parse(args.amount);
34
+ if (amount === 0n) {
35
+ throw new InvalidParametersException(args.chain, 'transfer amount must be > 0');
36
+ }
37
+ const data = encodeFunctionData({
38
+ abi: erc20Abi,
39
+ functionName: 'transfer',
40
+ args: [recipient, amount],
41
+ });
42
+ return {
43
+ to: token.address,
44
+ data,
45
+ value: 0n,
46
+ chainIdNumber: details.chainIdNumber,
47
+ };
48
+ }
49
+ /**
50
+ * Build an ERC-20 `approve(spender,uint256)` call.
51
+ *
52
+ * Hardening note: a 0 amount IS allowed here, because the safe
53
+ * approve-twice pattern (`approve(spender, 0)` followed by
54
+ * `approve(spender, N)`) is the only way to defeat the front-run
55
+ * race on legacy USDT-like contracts.
56
+ */
57
+ export function buildErc20Approve(args) {
58
+ const details = getChainDetails(args.chain, args.network);
59
+ const token = assertCanonicalTokenAddress({
60
+ chain: args.chain,
61
+ network: args.network,
62
+ symbol: args.tokenSymbol,
63
+ ...(args.claimedTokenAddress !== undefined
64
+ ? { claimedAddress: args.claimedTokenAddress }
65
+ : {}),
66
+ });
67
+ const spender = EvmAddressSchema.parse(args.spender);
68
+ const amount = Uint256Schema.parse(args.amount);
69
+ const data = encodeFunctionData({
70
+ abi: erc20Abi,
71
+ functionName: 'approve',
72
+ args: [spender, amount],
73
+ });
74
+ return {
75
+ to: token.address,
76
+ data,
77
+ value: 0n,
78
+ chainIdNumber: details.chainIdNumber,
79
+ };
80
+ }
81
+ /**
82
+ * Build an EIP-712 domain object pinned to a specific chain from the
83
+ * registry. The caller cannot smuggle a bogus chainId — it is derived
84
+ * from the (chain, network) pair, not user input.
85
+ */
86
+ export function buildEip712Domain(args) {
87
+ if (args.name.length === 0 || args.name.length > 64) {
88
+ throw new InvalidParametersException(args.chain, 'domain name length 1..64');
89
+ }
90
+ if (args.version.length === 0 || args.version.length > 16) {
91
+ throw new InvalidParametersException(args.chain, 'domain version length 1..16');
92
+ }
93
+ const details = getChainDetails(args.chain, args.network);
94
+ return {
95
+ name: args.name,
96
+ version: args.version,
97
+ chainId: details.chainIdNumber,
98
+ verifyingContract: EvmAddressSchema.parse(args.verifyingContract),
99
+ };
100
+ }
101
+ /* ------------------------- native-coin transfer --------------------------- */
102
+ export function buildNativeTransfer(args) {
103
+ const details = getChainDetails(args.chain, args.network);
104
+ const to = EvmAddressSchema.parse(args.to);
105
+ const amount = Uint256Schema.parse(args.amount);
106
+ if (amount === 0n) {
107
+ throw new InvalidParametersException(args.chain, 'transfer amount must be > 0');
108
+ }
109
+ return {
110
+ to,
111
+ data: '0x',
112
+ value: amount,
113
+ chainIdNumber: details.chainIdNumber,
114
+ };
115
+ }
116
+ //# sourceMappingURL=tx-builder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tx-builder.js","sourceRoot":"","sources":["../src/tx-builder.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,155 @@
1
+ /**
2
+ * Public types and zod schemas for @droplinked_inc/web3-kit.
3
+ *
4
+ * Every value crossing an external boundary (user-supplied chain id,
5
+ * token symbol, RPC URL, ABI-encoded payload) is validated against these
6
+ * schemas. See THREAT_MODEL.md for the rationale on each invariant.
7
+ */
8
+ import { z } from 'zod';
9
+ /**
10
+ * Canonical chain identifier used across the kit. String-valued so the
11
+ * representation is stable across JSON wire-formats and survives
12
+ * postMessage / fetch round-trips.
13
+ */
14
+ export declare enum Chains {
15
+ POLYGON = "POLYGON",
16
+ BINANCE = "BINANCE",
17
+ SKALE = "SKALE",
18
+ BASE = "BASE",
19
+ LINEA = "LINEA",
20
+ ETH = "ETH",
21
+ SOLANA = "SOLANA",
22
+ REDBELLY = "REDBELLY",
23
+ UNSTOPPABLE = "UNSTOPPABLE",
24
+ BITLAYER = "BITLAYER",
25
+ XION = "XION"
26
+ }
27
+ export declare enum Network {
28
+ TESTNET = "TESTNET",
29
+ MAINNET = "MAINNET"
30
+ }
31
+ export declare enum Groups {
32
+ EVM = "EVM",
33
+ SOL = "SOL",
34
+ BTC = "BTC",
35
+ XION = "XION",
36
+ UD = "UD"
37
+ }
38
+ export declare const ChainsSchema: z.ZodNativeEnum<typeof Chains>;
39
+ export declare const NetworkSchema: z.ZodNativeEnum<typeof Network>;
40
+ export declare const GroupsSchema: z.ZodNativeEnum<typeof Groups>;
41
+ export declare const EvmAddressSchema: z.ZodEffects<z.ZodString, `0x${string}`, string>;
42
+ export type EvmAddress = `0x${string}`;
43
+ export declare const HexStringSchema: z.ZodString;
44
+ /**
45
+ * Accepts the v1.0.13 wire-format for unsigned 256-bit numbers
46
+ * (`bigint`, base-10 string, non-negative finite integer) and
47
+ * normalizes to bigint. Negative, fractional, or out-of-range
48
+ * inputs are rejected.
49
+ */
50
+ export declare const Uint256Schema: z.ZodEffects<z.ZodEffects<z.ZodUnion<[z.ZodBigInt, z.ZodNumber, z.ZodString]>, bigint, string | number | bigint>, bigint, string | number | bigint>;
51
+ export type Uint256 = bigint;
52
+ /**
53
+ * Canonical short-symbol identifier for known fiat-equivalent or
54
+ * native tokens used during checkout. The set is intentionally small
55
+ * — anything outside is rejected by the registry to prevent symbol
56
+ * impersonation attacks (see THREAT_MODEL.md §4).
57
+ */
58
+ export declare enum PaymentTokens {
59
+ ETH = "ETH",
60
+ BNB = "BNB",
61
+ MATIC = "MATIC",
62
+ SOL = "SOL",
63
+ BTC = "BTC",
64
+ USDC = "USDC",
65
+ USDT = "USDT",
66
+ USDS = "USDS",
67
+ DAI = "DAI",
68
+ WETH = "WETH"
69
+ }
70
+ export declare const PaymentTokensSchema: z.ZodNativeEnum<typeof PaymentTokens>;
71
+ export declare const ChainPaymentSchema: z.ZodObject<{
72
+ totalPrice: z.ZodEffects<z.ZodEffects<z.ZodUnion<[z.ZodBigInt, z.ZodNumber, z.ZodString]>, bigint, string | number | bigint>, bigint, string | number | bigint>;
73
+ tbdValues: z.ZodArray<z.ZodEffects<z.ZodEffects<z.ZodUnion<[z.ZodBigInt, z.ZodNumber, z.ZodString]>, bigint, string | number | bigint>, bigint, string | number | bigint>, "many">;
74
+ tbdReceivers: z.ZodArray<z.ZodEffects<z.ZodString, `0x${string}`, string>, "many">;
75
+ tokenAddress: z.ZodOptional<z.ZodEffects<z.ZodString, `0x${string}`, string>>;
76
+ memo: z.ZodString;
77
+ chainLinkRoundId: z.ZodOptional<z.ZodString>;
78
+ }, "strip", z.ZodTypeAny, {
79
+ totalPrice: bigint;
80
+ tbdValues: bigint[];
81
+ tbdReceivers: `0x${string}`[];
82
+ memo: string;
83
+ tokenAddress?: `0x${string}` | undefined;
84
+ chainLinkRoundId?: string | undefined;
85
+ }, {
86
+ totalPrice: string | number | bigint;
87
+ tbdValues: (string | number | bigint)[];
88
+ tbdReceivers: string[];
89
+ memo: string;
90
+ tokenAddress?: string | undefined;
91
+ chainLinkRoundId?: string | undefined;
92
+ }>;
93
+ export type IChainPayment = z.infer<typeof ChainPaymentSchema>;
94
+ export declare const PurchaseConfirmationDataSchema: z.ZodArray<z.ZodObject<{
95
+ amount: z.ZodNumber;
96
+ productId: z.ZodString;
97
+ nullifier: z.ZodString;
98
+ }, "strip", z.ZodTypeAny, {
99
+ amount: number;
100
+ productId: string;
101
+ nullifier: string;
102
+ }, {
103
+ amount: number;
104
+ productId: string;
105
+ nullifier: string;
106
+ }>, "many">;
107
+ export declare const PurchaseSignatureSchema: z.ZodObject<{
108
+ signature: z.ZodString;
109
+ purchaseData: z.ZodArray<z.ZodObject<{
110
+ amount: z.ZodNumber;
111
+ productId: z.ZodString;
112
+ nullifier: z.ZodString;
113
+ }, "strip", z.ZodTypeAny, {
114
+ amount: number;
115
+ productId: string;
116
+ nullifier: string;
117
+ }, {
118
+ amount: number;
119
+ productId: string;
120
+ nullifier: string;
121
+ }>, "many">;
122
+ }, "strip", z.ZodTypeAny, {
123
+ signature: string;
124
+ purchaseData: {
125
+ amount: number;
126
+ productId: string;
127
+ nullifier: string;
128
+ }[];
129
+ }, {
130
+ signature: string;
131
+ purchaseData: {
132
+ amount: number;
133
+ productId: string;
134
+ nullifier: string;
135
+ }[];
136
+ }>;
137
+ export type PurchaseSignature = z.infer<typeof PurchaseSignatureSchema>;
138
+ export declare const ZERO_ADDRESS: EvmAddress;
139
+ export declare enum NFTType {
140
+ ERC1155 = 0,
141
+ ERC721 = 1
142
+ }
143
+ export declare enum ProductType {
144
+ DIGITAL = 0,
145
+ POD = 1,
146
+ PHYSICAL = 2
147
+ }
148
+ export declare enum Actions {
149
+ Payment = "Payment",
150
+ ClaimNFT = "ClaimNFT",
151
+ Record = "Record",
152
+ Auth = "Auth",
153
+ Login = "Login"
154
+ }
155
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAMxB;;;;GAIG;AACH,oBAAY,MAAM;IAChB,OAAO,YAAY;IACnB,OAAO,YAAY;IACnB,KAAK,UAAU;IACf,IAAI,SAAS;IACb,KAAK,UAAU;IACf,GAAG,QAAQ;IACX,MAAM,WAAW;IACjB,QAAQ,aAAa;IACrB,WAAW,gBAAgB;IAC3B,QAAQ,aAAa;IACrB,IAAI,SAAS;CACd;AAED,oBAAY,OAAO;IACjB,OAAO,YAAY;IACnB,OAAO,YAAY;CACpB;AAED,oBAAY,MAAM;IAChB,GAAG,QAAQ;IACX,GAAG,QAAQ;IACX,GAAG,QAAQ;IACX,IAAI,SAAS;IACb,EAAE,OAAO;CACV;AAED,eAAO,MAAM,YAAY,gCAAuB,CAAC;AACjD,eAAO,MAAM,aAAa,iCAAwB,CAAC;AACnD,eAAO,MAAM,YAAY,gCAAuB,CAAC;AAMjD,eAAO,MAAM,gBAAgB,kDAGwB,CAAC;AAEtD,MAAM,MAAM,UAAU,GAAG,KAAK,MAAM,EAAE,CAAC;AAEvC,eAAO,MAAM,eAAe,aAEuB,CAAC;AAEpD;;;;;GAKG;AACH,eAAO,MAAM,aAAa,qJAOiD,CAAC;AAE5E,MAAM,MAAM,OAAO,GAAG,MAAM,CAAC;AAM7B;;;;;GAKG;AACH,oBAAY,aAAa;IACvB,GAAG,QAAQ;IACX,GAAG,QAAQ;IACX,KAAK,UAAU;IACf,GAAG,QAAQ;IACX,GAAG,QAAQ;IACX,IAAI,SAAS;IACb,IAAI,SAAS;IACb,IAAI,SAAS;IACb,GAAG,QAAQ;IACX,IAAI,SAAS;CACd;AAED,eAAO,MAAM,mBAAmB,uCAA8B,CAAC;AAM/D,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;EAO7B,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAM/D,eAAO,MAAM,8BAA8B;;;;;;;;;;;;WAM1C,CAAC;AAEF,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAGlC,CAAC;AAEH,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAMxE,eAAO,MAAM,YAAY,EAAE,UAAyD,CAAC;AAErF,oBAAY,OAAO;IACjB,OAAO,IAAI;IACX,MAAM,IAAI;CACX;AAED,oBAAY,WAAW;IACrB,OAAO,IAAI;IACX,GAAG,IAAI;IACP,QAAQ,IAAI;CACb;AAED,oBAAY,OAAO;IACjB,OAAO,YAAY;IACnB,QAAQ,aAAa;IACrB,MAAM,WAAW;IACjB,IAAI,SAAS;IACb,KAAK,UAAU;CAChB"}