@magnaflow/chain-provider 1.0.2 → 1.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/README.md CHANGED
@@ -48,6 +48,57 @@ const balances = await provider.getBalances('0x1234...', [
48
48
 
49
49
  ## Notes
50
50
 
51
+ ### Polygon Mainnet
52
+
53
+ Only the exact `polygon_mainnet` key enables Polygon (137 / `0x89`, POL / 18,
54
+ Polygonscan). Aliases and Polygon testnets are not supported. Supply runtime
55
+ configuration from the API; the provider does not supply token or payout addresses.
56
+
57
+ ```ts
58
+ const polygonConfig = apiChainConfigs.find((config) => config.chain === 'polygon_mainnet');
59
+ if (!polygonConfig) throw new Error('Polygon is not enabled');
60
+ const polygonProvider = createChainProvider(polygonConfig);
61
+ const nativeBaseUnits = await polygonProvider.getNativeBalance(merchantAddress);
62
+ ```
63
+
64
+ Polygon uses nonempty `rpc_url`, falling back to `rest_url` only when empty.
65
+ Optional `chain_id` and `chainId` must both identify 137 when supplied. A supplied
66
+ native symbol must be `POL`, not `MATIC`. Public and wallet transports validate
67
+ `eth_chainId`, including direct client access and a fresh check before broadcasting.
68
+ Existing chains retain their RPC and fallback behavior. Balances remain raw base
69
+ units; consumers use runtime token decimals and POL's 18 native decimals.
70
+
71
+ Polygon support starts in `@magnaflow/chain-provider@1.1.0`. Keep application
72
+ dependencies, Bun overrides and lockfiles aligned with that release for CI installs.
73
+
74
+ For unreleased changes, build this workspace and pack/link this package locally.
75
+
76
+ For the current Kit checkout, its Bun overrides select the registry version even
77
+ after a link. Install the built tarball into that checkout's existing node_modules
78
+ for local integration, leaving its manifest and lockfile unchanged. Start in the
79
+ SDK repository root, with the Kit checkout in a sibling directory:
80
+
81
+ ```bash
82
+ polygon_pack_dir=$(mktemp -d "${TMPDIR:-/tmp}/polygon-provider-pack.XXXXXX")
83
+ bunx nx run chain-provider:build
84
+ cd packages/chain-provider
85
+ polygon_provider_version=$(bun -p 'require("./package.json").version')
86
+ bun pm pack --destination "$polygon_pack_dir"
87
+
88
+ cd ../../../merchant-tools-v2
89
+ polygon_backup=$(mktemp -d "${TMPDIR:-/tmp}/polygon-provider-backup.XXXXXX")
90
+ cp -R node_modules/@magnaflow/chain-provider "$polygon_backup/chain-provider"
91
+ tar -xzf "$polygon_pack_dir/magnaflow-chain-provider-$polygon_provider_version.tgz" --strip-components=1 -C node_modules/@magnaflow/chain-provider
92
+ bun -e 'import {createViemChainFromConfig} from "@magnaflow/chain-provider"; const chain = createViemChainFromConfig({chain:"polygon_mainnet",rpc_url:"https://rpc.example",rest_url:""}); console.log(chain.id, chain.nativeCurrency.symbol);'
93
+ bun run validate
94
+ bun run build
95
+ ```
96
+
97
+ The check prints `137 POL`. This package uses the workspace's bundler-style ESM
98
+ output; run this check with Bun, as used by Kit. A later dependency install can
99
+ replace the local package, so repeat the unpack and resolution check afterward.
100
+ The `rpc.example` value only verifies resolution and makes no network request.
101
+
51
102
  - The default EVM chain resolver is currently tuned for BSC and BSC testnet style configs.
52
103
  - `TronProvider` supports native transfers and balance queries. Advanced Tron contract interaction lives outside this package.
53
104
 
@@ -1 +1 @@
1
- {"version":3,"file":"evm-chain-utils.d.ts","sourceRoot":"","sources":["../src/evm-chain-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,MAAM,CAAC;AAClC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAG3C;;;GAGG;AACH,MAAM,MAAM,uBAAuB,GAAG,CAAC,MAAM,EAAE,WAAW,KAAK,KAAK,CAAC;AAErE;;;;;;;;GAQG;AACH,eAAO,MAAM,8BAA8B,EAAE,uBAyC5C,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,yBAAyB,EAAE,uBAAwD,CAAC"}
1
+ {"version":3,"file":"evm-chain-utils.d.ts","sourceRoot":"","sources":["../src/evm-chain-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,MAAM,CAAC;AAClC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAI3C;;;GAGG;AACH,MAAM,MAAM,uBAAuB,GAAG,CAAC,MAAM,EAAE,WAAW,KAAK,KAAK,CAAC;AAErE;;;;;;;;GAQG;AACH,eAAO,MAAM,8BAA8B,EAAE,uBAsD5C,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,yBAAyB,EAAE,uBAAwD,CAAC"}
@@ -1,4 +1,5 @@
1
1
  import { bscTestnet, bsc } from 'viem/chains';
2
+ import { getPolygonRpcUrl, isPolygonMainnet, POLYGON_MAINNET } from './polygon';
2
3
  /**
3
4
  * Implementation layer: default resolver that normalizes ChainConfig
4
5
  * into a viem Chain definition.
@@ -9,6 +10,18 @@ import { bscTestnet, bsc } from 'viem/chains';
9
10
  * - scan_url, if present, is used as the default block explorer URL.
10
11
  */
11
12
  export const defaultEvmChainRuntimeResolver = (chainConfig) => {
13
+ if (isPolygonMainnet(chainConfig.chain)) {
14
+ const rpc = getPolygonRpcUrl(chainConfig);
15
+ return {
16
+ ...POLYGON_MAINNET.preset,
17
+ nativeCurrency: POLYGON_MAINNET.nativeCurrency,
18
+ rpcUrls: { default: { http: [rpc] } },
19
+ blockExplorers: {
20
+ default: { name: 'Polygonscan', url: POLYGON_MAINNET.explorerUrl },
21
+ },
22
+ testnet: false,
23
+ };
24
+ }
12
25
  const isBscTestnet = chainConfig.rest_url.includes('prebsc') ||
13
26
  chainConfig.rest_url.includes('bsc-testnet') ||
14
27
  chainConfig.chain?.toLowerCase() === 'bsc_test';
@@ -33,9 +33,8 @@ export declare class EvmProvider implements ChainProvider {
33
33
  */
34
34
  getBlock(blockNumber?: bigint): Promise<{
35
35
  number: bigint;
36
- nonce: `0x${string}`;
37
36
  hash: `0x${string}`;
38
- gasUsed: bigint;
37
+ nonce: `0x${string}`;
39
38
  logsBloom: `0x${string}`;
40
39
  baseFeePerGas: bigint | null;
41
40
  blobGasUsed: bigint;
@@ -43,6 +42,7 @@ export declare class EvmProvider implements ChainProvider {
43
42
  excessBlobGas: bigint;
44
43
  extraData: import("viem").Hex;
45
44
  gasLimit: bigint;
45
+ gasUsed: bigint;
46
46
  miner: import("viem").Address;
47
47
  mixHash: import("viem").Hash;
48
48
  parentBeaconBlockRoot?: `0x${string}` | undefined;
@@ -64,129 +64,129 @@ export declare class EvmProvider implements ChainProvider {
64
64
  * Get transaction (using viem)
65
65
  */
66
66
  getTransaction(txHash: string): Promise<{
67
+ type: "legacy";
68
+ value: bigint;
69
+ yParity?: undefined | undefined;
67
70
  from: import("viem").Address;
68
71
  gas: bigint;
72
+ hash: import("viem").Hash;
73
+ input: import("viem").Hex;
69
74
  nonce: number;
70
- to: import("viem").Address | null;
71
- type: "legacy";
72
- value: bigint;
73
75
  r: import("viem").Hex;
74
76
  s: import("viem").Hex;
77
+ to: import("viem").Address | null;
78
+ typeHex: import("viem").Hex | null;
75
79
  v: bigint;
76
- yParity?: undefined | undefined;
80
+ accessList?: undefined | undefined;
81
+ authorizationList?: undefined | undefined;
77
82
  blobVersionedHashes?: undefined | undefined;
83
+ chainId?: number | undefined;
78
84
  gasPrice: bigint;
79
85
  maxFeePerBlobGas?: undefined | undefined;
80
86
  maxFeePerGas?: undefined | undefined;
81
87
  maxPriorityFeePerGas?: undefined | undefined;
82
- chainId?: number | undefined;
83
- accessList?: undefined | undefined;
84
- authorizationList?: undefined | undefined;
85
- hash: import("viem").Hash;
86
- input: import("viem").Hex;
87
- typeHex: import("viem").Hex | null;
88
- blockNumber: bigint;
89
88
  blockHash: `0x${string}`;
89
+ blockNumber: bigint;
90
90
  transactionIndex: number;
91
91
  } | {
92
+ type: "eip2930";
93
+ value: bigint;
94
+ yParity: number;
92
95
  from: import("viem").Address;
93
96
  gas: bigint;
97
+ hash: import("viem").Hash;
98
+ input: import("viem").Hex;
94
99
  nonce: number;
95
- to: import("viem").Address | null;
96
- type: "eip2930";
97
- value: bigint;
98
100
  r: import("viem").Hex;
99
101
  s: import("viem").Hex;
102
+ to: import("viem").Address | null;
103
+ typeHex: import("viem").Hex | null;
100
104
  v: bigint;
101
- yParity: number;
105
+ accessList: import("viem").AccessList;
106
+ authorizationList?: undefined | undefined;
102
107
  blobVersionedHashes?: undefined | undefined;
108
+ chainId: number;
103
109
  gasPrice: bigint;
104
110
  maxFeePerBlobGas?: undefined | undefined;
105
111
  maxFeePerGas?: undefined | undefined;
106
112
  maxPriorityFeePerGas?: undefined | undefined;
107
- chainId: number;
108
- accessList: import("viem").AccessList;
109
- authorizationList?: undefined | undefined;
110
- hash: import("viem").Hash;
111
- input: import("viem").Hex;
112
- typeHex: import("viem").Hex | null;
113
- blockNumber: bigint;
114
113
  blockHash: `0x${string}`;
114
+ blockNumber: bigint;
115
115
  transactionIndex: number;
116
116
  } | {
117
+ type: "eip1559";
118
+ value: bigint;
119
+ yParity: number;
117
120
  from: import("viem").Address;
118
121
  gas: bigint;
122
+ hash: import("viem").Hash;
123
+ input: import("viem").Hex;
119
124
  nonce: number;
120
- to: import("viem").Address | null;
121
- type: "eip1559";
122
- value: bigint;
123
125
  r: import("viem").Hex;
124
126
  s: import("viem").Hex;
127
+ to: import("viem").Address | null;
128
+ typeHex: import("viem").Hex | null;
125
129
  v: bigint;
126
- yParity: number;
130
+ accessList: import("viem").AccessList;
131
+ authorizationList?: undefined | undefined;
127
132
  blobVersionedHashes?: undefined | undefined;
133
+ chainId: number;
128
134
  gasPrice?: undefined | undefined;
129
135
  maxFeePerBlobGas?: undefined | undefined;
130
136
  maxFeePerGas: bigint;
131
137
  maxPriorityFeePerGas: bigint;
132
- chainId: number;
133
- accessList: import("viem").AccessList;
134
- authorizationList?: undefined | undefined;
135
- hash: import("viem").Hash;
136
- input: import("viem").Hex;
137
- typeHex: import("viem").Hex | null;
138
- blockNumber: bigint;
139
138
  blockHash: `0x${string}`;
139
+ blockNumber: bigint;
140
140
  transactionIndex: number;
141
141
  } | {
142
+ type: "eip4844";
143
+ value: bigint;
144
+ yParity: number;
142
145
  from: import("viem").Address;
143
146
  gas: bigint;
147
+ hash: import("viem").Hash;
148
+ input: import("viem").Hex;
144
149
  nonce: number;
145
- to: import("viem").Address | null;
146
- type: "eip4844";
147
- value: bigint;
148
150
  r: import("viem").Hex;
149
151
  s: import("viem").Hex;
152
+ to: import("viem").Address | null;
153
+ typeHex: import("viem").Hex | null;
150
154
  v: bigint;
151
- yParity: number;
155
+ accessList: import("viem").AccessList;
156
+ authorizationList?: undefined | undefined;
152
157
  blobVersionedHashes: readonly import("viem").Hex[];
158
+ chainId: number;
153
159
  gasPrice?: undefined | undefined;
154
160
  maxFeePerBlobGas: bigint;
155
161
  maxFeePerGas: bigint;
156
162
  maxPriorityFeePerGas: bigint;
157
- chainId: number;
158
- accessList: import("viem").AccessList;
159
- authorizationList?: undefined | undefined;
160
- hash: import("viem").Hash;
161
- input: import("viem").Hex;
162
- typeHex: import("viem").Hex | null;
163
- blockNumber: bigint;
164
163
  blockHash: `0x${string}`;
164
+ blockNumber: bigint;
165
165
  transactionIndex: number;
166
166
  } | {
167
+ type: "eip7702";
168
+ value: bigint;
169
+ yParity: number;
167
170
  from: import("viem").Address;
168
171
  gas: bigint;
172
+ hash: import("viem").Hash;
173
+ input: import("viem").Hex;
169
174
  nonce: number;
170
- to: import("viem").Address | null;
171
- type: "eip7702";
172
- value: bigint;
173
175
  r: import("viem").Hex;
174
176
  s: import("viem").Hex;
177
+ to: import("viem").Address | null;
178
+ typeHex: import("viem").Hex | null;
175
179
  v: bigint;
176
- yParity: number;
180
+ accessList: import("viem").AccessList;
181
+ authorizationList: import("viem").SignedAuthorizationList;
177
182
  blobVersionedHashes?: undefined | undefined;
183
+ chainId: number;
178
184
  gasPrice?: undefined | undefined;
179
185
  maxFeePerBlobGas?: undefined | undefined;
180
186
  maxFeePerGas: bigint;
181
187
  maxPriorityFeePerGas: bigint;
182
- chainId: number;
183
- accessList: import("viem").AccessList;
184
- authorizationList: import("viem").SignedAuthorizationList;
185
- hash: import("viem").Hash;
186
- input: import("viem").Hex;
187
- typeHex: import("viem").Hex | null;
188
- blockNumber: bigint;
189
188
  blockHash: `0x${string}`;
189
+ blockNumber: bigint;
190
190
  transactionIndex: number;
191
191
  }>;
192
192
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"evm-provider.d.ts","sourceRoot":"","sources":["../src/evm-provider.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAIL,KAAK,YAAY,EAEjB,KAAK,YAAY,EAElB,MAAM,MAAM,CAAC;AAEd,OAAO,KAAK,EACV,WAAW,EACX,WAAW,EACX,kBAAkB,EAClB,iBAAiB,EACjB,kBAAkB,EACnB,MAAM,SAAS,CAAC;AACjB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAItD;;GAEG;AACH,qBAAa,WAAY,YAAW,aAAa;IAC/C,OAAO,CAAC,WAAW,CAAc;IACjC,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,KAAK,CAAQ;IACrB,OAAO,CAAC,OAAO,CAAC,CAAU;gBAEd,WAAW,EAAE,WAAW,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,YAAY,GAAE,MAAU;IAgBjF,YAAY,IAAI,KAAK;IAIf,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAOlD,eAAe,CAAC,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAuB1F,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,cAAc,GAAE,MAAM,EAAO,GAAG,OAAO,CAAC,WAAW,CAAC;IAuCjF,eAAe,CACnB,KAAK,EAAE,MAAM,EACb,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,kBAAkB,GAC3B,OAAO,CAAC,iBAAiB,CAAC;IAmCvB,kBAAkB,CACtB,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,aAAa,CAAC,EAAE,MAAM,CAAA;KAAE,GACrD,OAAO,CAAC,kBAAkB,CAAC;IAmBxB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC;IAoBzE,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAU3F;;OAEG;IACG,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC;IAIvC;;OAEG;IACG,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAOnC;;OAEG;IACG,cAAc,CAAC,MAAM,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAMnC;;OAEG;IACG,UAAU;IAIhB;;OAEG;IACH,eAAe,IAAI,YAAY;IAI/B;;;OAGG;IACH,OAAO,CAAC,aAAa,CAA6B;IAClD,eAAe,IAAI,YAAY,GAAG,IAAI;CAavC"}
1
+ {"version":3,"file":"evm-provider.d.ts","sourceRoot":"","sources":["../src/evm-provider.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAIL,KAAK,YAAY,EAEjB,KAAK,YAAY,EAElB,MAAM,MAAM,CAAC;AAEd,OAAO,KAAK,EACV,WAAW,EACX,WAAW,EACX,kBAAkB,EAClB,iBAAiB,EACjB,kBAAkB,EACnB,MAAM,SAAS,CAAC;AACjB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAKtD;;GAEG;AACH,qBAAa,WAAY,YAAW,aAAa;IAC/C,OAAO,CAAC,WAAW,CAAc;IACjC,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,KAAK,CAAQ;IACrB,OAAO,CAAC,OAAO,CAAC,CAAU;gBAEd,WAAW,EAAE,WAAW,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,YAAY,GAAE,MAAU;IAkBjF,YAAY,IAAI,KAAK;IAIf,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAOlD,eAAe,CAAC,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAuB1F,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,cAAc,GAAE,MAAM,EAAO,GAAG,OAAO,CAAC,WAAW,CAAC;IAuCjF,eAAe,CACnB,KAAK,EAAE,MAAM,EACb,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,kBAAkB,GAC3B,OAAO,CAAC,iBAAiB,CAAC;IAmCvB,kBAAkB,CACtB,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,aAAa,CAAC,EAAE,MAAM,CAAA;KAAE,GACrD,OAAO,CAAC,kBAAkB,CAAC;IAmBxB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC;IAuBzE,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAU3F;;OAEG;IACG,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC;IAIvC;;OAEG;IACG,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAOnC;;OAEG;IACG,cAAc,CAAC,MAAM,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAMnC;;OAEG;IACG,UAAU;IAIhB;;OAEG;IACH,eAAe,IAAI,YAAY;IAI/B;;;OAGG;IACH,OAAO,CAAC,aAAa,CAA6B;IAClD,eAAe,IAAI,YAAY,GAAG,IAAI;CAevC"}
@@ -5,6 +5,7 @@ import { createPublicClient, createWalletClient, http, } from 'viem';
5
5
  import { mnemonicToAccount } from 'viem/accounts';
6
6
  import { DERIVATION_PATH_BASE, buildDerivationPath } from '@magnaflow/eoa-wallet';
7
7
  import { createViemChainFromConfig } from './evm-chain-utils';
8
+ import { createPolygonTransport, isPolygonMainnet, isPolygonConfigurationError } from './polygon';
8
9
  /**
9
10
  * EVM chain provider
10
11
  */
@@ -19,7 +20,9 @@ export class EvmProvider {
19
20
  this.chain = createViemChainFromConfig(chainConfig);
20
21
  this.publicClient = createPublicClient({
21
22
  chain: this.chain,
22
- transport: http(chainConfig.rest_url),
23
+ transport: isPolygonMainnet(chainConfig.chain)
24
+ ? createPolygonTransport(chainConfig)
25
+ : http(chainConfig.rest_url),
23
26
  });
24
27
  if (mnemonic) {
25
28
  const path = buildDerivationPath(DERIVATION_PATH_BASE.evm, accountIndex);
@@ -155,7 +158,10 @@ export class EvmProvider {
155
158
  effectiveGasPrice: receipt.effectiveGasPrice,
156
159
  };
157
160
  }
158
- catch {
161
+ catch (error) {
162
+ if (isPolygonMainnet(this.chainConfig.chain) && isPolygonConfigurationError(error)) {
163
+ throw error;
164
+ }
159
165
  return null;
160
166
  }
161
167
  }
@@ -210,7 +216,9 @@ export class EvmProvider {
210
216
  this._walletClient = createWalletClient({
211
217
  account: this.account,
212
218
  chain: this.chain,
213
- transport: http(this.chainConfig.rest_url),
219
+ transport: isPolygonMainnet(this.chainConfig.chain)
220
+ ? createPolygonTransport(this.chainConfig)
221
+ : http(this.chainConfig.rest_url),
214
222
  });
215
223
  }
216
224
  return this._walletClient;
package/dist/index.d.ts CHANGED
@@ -7,5 +7,7 @@ export type { ChainProvider } from './chain-provider';
7
7
  export { EvmProvider } from './evm-provider';
8
8
  export { TronProvider } from './tron-provider';
9
9
  export { createViemChainFromConfig } from './evm-chain-utils';
10
+ export { POLYGON_MAINNET, PolygonConfigurationError, isPolygonMainnet, assertPolygonChainId, getPolygonRpcUrl, createPolygonTransport, isPolygonConfigurationError, } from './polygon';
11
+ export type { PolygonRuntimeConfig } from './polygon';
10
12
  export { getChainType, createChainProvider, createEvmProvider, createTronProvider, } from './chain-factory';
11
13
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,YAAY,EACV,SAAS,EACT,WAAW,EACX,WAAW,EACX,WAAW,EACX,kBAAkB,EAClB,iBAAiB,EACjB,kBAAkB,GACnB,MAAM,SAAS,CAAC;AAGjB,YAAY,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAGtD,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,yBAAyB,EAAE,MAAM,mBAAmB,CAAC;AAG9D,OAAO,EACL,YAAY,EACZ,mBAAmB,EACnB,iBAAiB,EACjB,kBAAkB,GACnB,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,YAAY,EACV,SAAS,EACT,WAAW,EACX,WAAW,EACX,WAAW,EACX,kBAAkB,EAClB,iBAAiB,EACjB,kBAAkB,GACnB,MAAM,SAAS,CAAC;AAGjB,YAAY,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAGtD,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,yBAAyB,EAAE,MAAM,mBAAmB,CAAC;AAC9D,OAAO,EACL,eAAe,EACf,yBAAyB,EACzB,gBAAgB,EAChB,oBAAoB,EACpB,gBAAgB,EAChB,sBAAsB,EACtB,2BAA2B,GAC5B,MAAM,WAAW,CAAC;AACnB,YAAY,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AAGtD,OAAO,EACL,YAAY,EACZ,mBAAmB,EACnB,iBAAiB,EACjB,kBAAkB,GACnB,MAAM,iBAAiB,CAAC"}
package/dist/index.js CHANGED
@@ -6,5 +6,6 @@
6
6
  export { EvmProvider } from './evm-provider';
7
7
  export { TronProvider } from './tron-provider';
8
8
  export { createViemChainFromConfig } from './evm-chain-utils';
9
+ export { POLYGON_MAINNET, PolygonConfigurationError, isPolygonMainnet, assertPolygonChainId, getPolygonRpcUrl, createPolygonTransport, isPolygonConfigurationError, } from './polygon';
9
10
  // Factory
10
11
  export { getChainType, createChainProvider, createEvmProvider, createTronProvider, } from './chain-factory';
@@ -0,0 +1,74 @@
1
+ import { type HttpTransportConfig, type Transport } from 'viem';
2
+ export declare const POLYGON_MAINNET: {
3
+ readonly key: "polygon_mainnet";
4
+ readonly id: 137;
5
+ readonly hexId: "0x89";
6
+ readonly preset: {
7
+ blockExplorers: {
8
+ readonly default: {
9
+ readonly name: "PolygonScan";
10
+ readonly url: "https://polygonscan.com";
11
+ readonly apiUrl: "https://api.etherscan.io/v2/api";
12
+ };
13
+ };
14
+ blockTime: 2000;
15
+ contracts: {
16
+ readonly multicall3: {
17
+ readonly address: "0xca11bde05977b3631167028862be2a173976ca11";
18
+ readonly blockCreated: 25770160;
19
+ };
20
+ };
21
+ ensTlds?: readonly string[] | undefined;
22
+ id: 137;
23
+ name: "Polygon";
24
+ nativeCurrency: {
25
+ readonly name: "POL";
26
+ readonly symbol: "POL";
27
+ readonly decimals: 18;
28
+ };
29
+ experimental_preconfirmationTime?: number | undefined | undefined;
30
+ rpcUrls: {
31
+ readonly default: {
32
+ readonly http: readonly ["https://polygon.drpc.org"];
33
+ };
34
+ };
35
+ sourceId?: number | undefined | undefined;
36
+ testnet?: boolean | undefined | undefined;
37
+ custom?: Record<string, unknown> | undefined;
38
+ extendSchema?: Record<string, unknown> | undefined;
39
+ fees?: import("viem").ChainFees<undefined> | undefined;
40
+ formatters?: undefined;
41
+ prepareTransactionRequest?: ((args: import("viem").PrepareTransactionRequestParameters, options: {
42
+ phase: "beforeFillTransaction" | "beforeFillParameters" | "afterFillParameters";
43
+ }) => Promise<import("viem").PrepareTransactionRequestParameters>) | [fn: ((args: import("viem").PrepareTransactionRequestParameters, options: {
44
+ phase: "beforeFillTransaction" | "beforeFillParameters" | "afterFillParameters";
45
+ }) => Promise<import("viem").PrepareTransactionRequestParameters>) | undefined, options: {
46
+ runAt: readonly ("beforeFillTransaction" | "beforeFillParameters" | "afterFillParameters")[];
47
+ }] | undefined;
48
+ serializers?: import("viem").ChainSerializers<undefined, import("viem").TransactionSerializable> | undefined;
49
+ verifyHash?: ((client: import("viem").Client, parameters: import("viem").VerifyHashActionParameters) => Promise<import("viem").VerifyHashActionReturnType>) | undefined;
50
+ };
51
+ readonly nativeCurrency: {
52
+ readonly name: "POL";
53
+ readonly symbol: "POL";
54
+ readonly decimals: 18;
55
+ };
56
+ readonly explorerUrl: "https://polygonscan.com/";
57
+ readonly testnet: false;
58
+ };
59
+ export interface PolygonRuntimeConfig {
60
+ chain: string;
61
+ rpc_url?: string;
62
+ rest_url?: string;
63
+ chain_id?: number | string;
64
+ chainId?: number | string;
65
+ }
66
+ export declare class PolygonConfigurationError extends Error {
67
+ constructor(message: string);
68
+ }
69
+ export declare const isPolygonMainnet: (chain: unknown) => chain is "polygon_mainnet";
70
+ export declare function assertPolygonChainId(value: unknown): void;
71
+ export declare function getPolygonRpcUrl(config: PolygonRuntimeConfig): string;
72
+ export declare function isPolygonConfigurationError(error: unknown): boolean;
73
+ export declare function createPolygonTransport(config: PolygonRuntimeConfig, options?: HttpTransportConfig): Transport;
74
+ //# sourceMappingURL=polygon.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"polygon.d.ts","sourceRoot":"","sources":["../src/polygon.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,KAAK,mBAAmB,EAAE,KAAK,SAAS,EAAE,MAAM,MAAM,CAAC;AAGtE,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAQlB,CAAC;AAEX,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC3B,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CAC3B;AAED,qBAAa,yBAA0B,SAAQ,KAAK;gBACtC,OAAO,EAAE,MAAM;CAI5B;AAED,eAAO,MAAM,gBAAgB,GAAI,OAAO,OAAO,KAAG,KAAK,IAAI,iBAC5B,CAAC;AAEhC,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CASzD;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,oBAAoB,GAAG,MAAM,CAkCrE;AAED,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CASnE;AAED,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,oBAAoB,EAC5B,OAAO,CAAC,EAAE,mBAAmB,GAC5B,SAAS,CAwCX"}
@@ -0,0 +1,115 @@
1
+ import { http } from 'viem';
2
+ import { polygon } from 'viem/chains';
3
+ export const POLYGON_MAINNET = {
4
+ key: 'polygon_mainnet',
5
+ id: 137,
6
+ hexId: '0x89',
7
+ preset: polygon,
8
+ nativeCurrency: { name: 'POL', symbol: 'POL', decimals: 18 },
9
+ explorerUrl: 'https://polygonscan.com/',
10
+ testnet: false,
11
+ };
12
+ export class PolygonConfigurationError extends Error {
13
+ constructor(message) {
14
+ super(message);
15
+ this.name = 'PolygonConfigurationError';
16
+ }
17
+ }
18
+ export const isPolygonMainnet = (chain) => chain === POLYGON_MAINNET.key;
19
+ export function assertPolygonChainId(value) {
20
+ const validNumber = typeof value === 'number' && value === POLYGON_MAINNET.id;
21
+ const validString = typeof value === 'string' &&
22
+ /^(?:[0-9]+|0[xX][0-9a-fA-F]+)$/.test(value.trim()) &&
23
+ BigInt(value.trim()) === BigInt(POLYGON_MAINNET.id);
24
+ if (!validNumber && !validString) {
25
+ throw new PolygonConfigurationError('Polygon requires chain ID 137 (0x89).');
26
+ }
27
+ }
28
+ export function getPolygonRpcUrl(config) {
29
+ if (!isPolygonMainnet(config.chain)) {
30
+ throw new PolygonConfigurationError('Unsupported Polygon chain key.');
31
+ }
32
+ if (config.chain_id !== undefined)
33
+ assertPolygonChainId(config.chain_id);
34
+ if (config.chainId !== undefined)
35
+ assertPolygonChainId(config.chainId);
36
+ const symbol = config.symbol;
37
+ if (symbol !== undefined && symbol !== 'POL') {
38
+ throw new PolygonConfigurationError('Polygon native symbol must be POL.');
39
+ }
40
+ if (config.rpc_url !== undefined &&
41
+ config.rpc_url !== null &&
42
+ typeof config.rpc_url !== 'string') {
43
+ throw new PolygonConfigurationError('Polygon runtime RPC URL is invalid.');
44
+ }
45
+ const primaryRpc = config.rpc_url?.trim();
46
+ if (!primaryRpc &&
47
+ config.rest_url !== undefined &&
48
+ config.rest_url !== null &&
49
+ typeof config.rest_url !== 'string') {
50
+ throw new PolygonConfigurationError('Polygon runtime RPC URL is invalid.');
51
+ }
52
+ const rpc = primaryRpc || config.rest_url?.trim() || '';
53
+ try {
54
+ const url = new URL(rpc);
55
+ if (url.protocol !== 'https:' && url.protocol !== 'http:')
56
+ throw new Error();
57
+ }
58
+ catch {
59
+ throw new PolygonConfigurationError('Polygon runtime RPC URL is missing or invalid.');
60
+ }
61
+ return rpc;
62
+ }
63
+ export function isPolygonConfigurationError(error) {
64
+ const visited = new Set();
65
+ let current = error;
66
+ while (current && typeof current === 'object' && !visited.has(current)) {
67
+ visited.add(current);
68
+ if ('name' in current && current.name === 'PolygonConfigurationError')
69
+ return true;
70
+ current = 'cause' in current ? current.cause : undefined;
71
+ }
72
+ return false;
73
+ }
74
+ export function createPolygonTransport(config, options) {
75
+ const rpc = getPolygonRpcUrl(config);
76
+ return (parameters) => {
77
+ const transport = http(rpc, options)(parameters);
78
+ let verified = false;
79
+ let pending;
80
+ const verify = (force = false) => {
81
+ if (pending)
82
+ return pending;
83
+ if (verified && !force)
84
+ return Promise.resolve();
85
+ pending = transport
86
+ .request({ method: 'eth_chainId' })
87
+ .then((value) => {
88
+ assertPolygonChainId(value);
89
+ verified = true;
90
+ })
91
+ .catch((error) => {
92
+ verified = false;
93
+ throw error;
94
+ })
95
+ .finally(() => {
96
+ pending = undefined;
97
+ });
98
+ return pending;
99
+ };
100
+ return {
101
+ ...transport,
102
+ request: (async (args, requestOptions) => {
103
+ const method = args.method;
104
+ // Recheck before broadcasting, including direct wallet-client requests.
105
+ await verify(method === 'eth_chainId' ||
106
+ method === 'eth_sendRawTransaction' ||
107
+ method === 'eth_sendTransaction' ||
108
+ method === 'wallet_sendCalls');
109
+ if (method === 'eth_chainId')
110
+ return POLYGON_MAINNET.hexId;
111
+ return transport.request(args, requestOptions);
112
+ }),
113
+ };
114
+ };
115
+ }
package/dist/types.d.ts CHANGED
@@ -12,6 +12,8 @@ export interface ChainConfig {
12
12
  rest_url: string;
13
13
  payout_contract: string;
14
14
  scan_url?: string;
15
+ chain_id?: number | string;
16
+ chainId?: number | string;
15
17
  tokens?: TokenConfig[];
16
18
  }
17
19
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,MAAM,SAAS,GAAG,KAAK,GAAG,MAAM,CAAC;AAEvC;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,WAAW,EAAE,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChC;AAED;;;;;;;;;;GAUG;AACH,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,SAAS,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,SAAS,GAAG,QAAQ,CAAC;IAC7B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,MAAM,SAAS,GAAG,KAAK,GAAG,MAAM,CAAC;AAEvC;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC3B,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC1B,MAAM,CAAC,EAAE,WAAW,EAAE,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChC;AAED;;;;;;;;;;GAUG;AACH,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,SAAS,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,SAAS,GAAG,QAAQ,CAAC;IAC7B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@magnaflow/chain-provider",
3
- "version": "1.0.2",
3
+ "version": "1.1.0",
4
4
  "description": "Chain provider abstraction library for unified blockchain interactions",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",