@chorus-one/polygon 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/.mocharc.json +6 -0
  2. package/LICENSE +13 -0
  3. package/README.md +233 -0
  4. package/dist/cjs/constants.d.ts +187 -0
  5. package/dist/cjs/constants.js +141 -0
  6. package/dist/cjs/index.d.ts +4 -0
  7. package/dist/cjs/index.js +12 -0
  8. package/dist/cjs/package.json +3 -0
  9. package/dist/cjs/referrer.d.ts +2 -0
  10. package/dist/cjs/referrer.js +15 -0
  11. package/dist/cjs/staker.d.ts +335 -0
  12. package/dist/cjs/staker.js +716 -0
  13. package/dist/cjs/types.d.ts +40 -0
  14. package/dist/cjs/types.js +2 -0
  15. package/dist/mjs/constants.d.ts +187 -0
  16. package/dist/mjs/constants.js +138 -0
  17. package/dist/mjs/index.d.ts +4 -0
  18. package/dist/mjs/index.js +2 -0
  19. package/dist/mjs/package.json +3 -0
  20. package/dist/mjs/referrer.d.ts +2 -0
  21. package/dist/mjs/referrer.js +11 -0
  22. package/dist/mjs/staker.d.ts +335 -0
  23. package/dist/mjs/staker.js +712 -0
  24. package/dist/mjs/types.d.ts +40 -0
  25. package/dist/mjs/types.js +1 -0
  26. package/hardhat.config.ts +27 -0
  27. package/package.json +50 -0
  28. package/src/constants.ts +151 -0
  29. package/src/index.ts +14 -0
  30. package/src/referrer.ts +15 -0
  31. package/src/staker.ts +878 -0
  32. package/src/types.ts +45 -0
  33. package/test/fixtures/expected-data.ts +17 -0
  34. package/test/integration/localSigner.spec.ts +128 -0
  35. package/test/integration/setup.ts +41 -0
  36. package/test/integration/staker.spec.ts +587 -0
  37. package/test/integration/testStaker.ts +130 -0
  38. package/test/integration/utils.ts +263 -0
  39. package/test/lib/networks.json +14 -0
  40. package/test/staker.spec.ts +154 -0
  41. package/tsconfig.cjs.json +9 -0
  42. package/tsconfig.json +13 -0
  43. package/tsconfig.mjs.json +9 -0
@@ -0,0 +1,130 @@
1
+ import { PolygonStaker, CHORUS_ONE_POLYGON_VALIDATORS } from '@chorus-one/polygon'
2
+ import { LocalSigner } from '@chorus-one/signer-local'
3
+ import { KeyType } from '@chorus-one/signer'
4
+ import * as bip39 from 'bip39'
5
+ import { HDKey } from '@scure/bip32'
6
+ import type { Address, PublicClient } from 'viem'
7
+ import { createPublicClient, http } from 'viem'
8
+ import { hardhat } from 'viem/chains'
9
+
10
+ export class PolygonTestStaker {
11
+ private mnemonic: string
12
+ public hdPath: string
13
+ public delegatorAddress: Address
14
+ public validatorShareAddress: Address
15
+ public staker: PolygonStaker
16
+ public localSigner: LocalSigner
17
+ public publicClient: PublicClient
18
+
19
+ constructor (params: { mnemonic: string; rpcUrl: string }) {
20
+ if (!params.mnemonic) {
21
+ throw new Error('Mnemonic is required')
22
+ }
23
+
24
+ this.mnemonic = params.mnemonic
25
+ this.hdPath = "m/44'/60'/0'/0/0"
26
+ this.validatorShareAddress = CHORUS_ONE_POLYGON_VALIDATORS.mainnet
27
+
28
+ this.staker = new PolygonStaker({
29
+ network: 'mainnet',
30
+ rpcUrl: params.rpcUrl
31
+ })
32
+
33
+ this.publicClient = createPublicClient({
34
+ chain: hardhat,
35
+ transport: http(params.rpcUrl)
36
+ })
37
+ }
38
+
39
+ async init (): Promise<void> {
40
+ const seed = bip39.mnemonicToSeedSync(this.mnemonic)
41
+ const hdKey = HDKey.fromMasterSeed(seed)
42
+ const derived = hdKey.derive(this.hdPath)
43
+ const publicKey = derived.publicKey
44
+
45
+ if (!publicKey) {
46
+ throw new Error('Failed to derive public key')
47
+ }
48
+
49
+ const addressDerivationFn = PolygonStaker.getAddressDerivationFn()
50
+ const addresses = await addressDerivationFn(publicKey)
51
+ this.delegatorAddress = `0x${addresses[0]}` as Address
52
+
53
+ this.localSigner = new LocalSigner({
54
+ mnemonic: this.mnemonic,
55
+ accounts: [{ hdPath: this.hdPath }],
56
+ keyType: KeyType.SECP256K1,
57
+ addressDerivationFn
58
+ })
59
+ await this.localSigner.init()
60
+ }
61
+
62
+ private async waitForTx (txHash: `0x${string}`): Promise<void> {
63
+ const receipt = await this.publicClient.waitForTransactionReceipt({ hash: txHash })
64
+ if (receipt.status !== 'success') {
65
+ throw new Error(`Transaction failed: ${txHash}`)
66
+ }
67
+ }
68
+
69
+ async approve (amount: string): Promise<string> {
70
+ const { tx } = await this.staker.buildApproveTx({ amount })
71
+ const { signedTx } = await this.staker.sign({
72
+ signer: this.localSigner,
73
+ signerAddress: this.delegatorAddress,
74
+ tx
75
+ })
76
+ const { txHash } = await this.staker.broadcast({ signedTx })
77
+ await this.waitForTx(txHash)
78
+ return txHash
79
+ }
80
+
81
+ async stake (amount: string, minSharesToMint: bigint): Promise<string> {
82
+ const { tx } = await this.staker.buildStakeTx({
83
+ delegatorAddress: this.delegatorAddress,
84
+ validatorShareAddress: this.validatorShareAddress,
85
+ amount,
86
+ minSharesToMint
87
+ })
88
+ const { signedTx } = await this.staker.sign({
89
+ signer: this.localSigner,
90
+ signerAddress: this.delegatorAddress,
91
+ tx
92
+ })
93
+ const { txHash } = await this.staker.broadcast({ signedTx })
94
+ await this.waitForTx(txHash)
95
+ return txHash
96
+ }
97
+
98
+ async unstake (amount: string, maximumSharesToBurn: bigint): Promise<string> {
99
+ const { tx } = await this.staker.buildUnstakeTx({
100
+ delegatorAddress: this.delegatorAddress,
101
+ validatorShareAddress: this.validatorShareAddress,
102
+ amount,
103
+ maximumSharesToBurn
104
+ })
105
+ const { signedTx } = await this.staker.sign({
106
+ signer: this.localSigner,
107
+ signerAddress: this.delegatorAddress,
108
+ tx
109
+ })
110
+ const { txHash } = await this.staker.broadcast({ signedTx })
111
+ await this.waitForTx(txHash)
112
+ return txHash
113
+ }
114
+
115
+ async withdraw (unbondNonce: bigint): Promise<string> {
116
+ const { tx } = await this.staker.buildWithdrawTx({
117
+ delegatorAddress: this.delegatorAddress,
118
+ validatorShareAddress: this.validatorShareAddress,
119
+ unbondNonce
120
+ })
121
+ const { signedTx } = await this.staker.sign({
122
+ signer: this.localSigner,
123
+ signerAddress: this.delegatorAddress,
124
+ tx
125
+ })
126
+ const { txHash } = await this.staker.broadcast({ signedTx })
127
+ await this.waitForTx(txHash)
128
+ return txHash
129
+ }
130
+ }
@@ -0,0 +1,263 @@
1
+ import { PolygonStaker, CHORUS_ONE_POLYGON_VALIDATORS, NETWORK_CONTRACTS, type Transaction } from '@chorus-one/polygon'
2
+ import {
3
+ createWalletClient,
4
+ createPublicClient,
5
+ http,
6
+ erc20Abi,
7
+ encodeFunctionData,
8
+ parseEther,
9
+ toHex,
10
+ type PublicClient,
11
+ type WalletClient,
12
+ type Hex,
13
+ type Address
14
+ } from 'viem'
15
+ import { privateKeyToAccount } from 'viem/accounts'
16
+ import { hardhat } from 'viem/chains'
17
+ import { assert } from 'chai'
18
+ import networkConfig from '../lib/networks.json'
19
+
20
+ export interface TestSetup {
21
+ validatorShareAddress: Address
22
+ walletClient: WalletClient
23
+ publicClient: PublicClient
24
+ staker: PolygonStaker
25
+ delegatorAddress: Address
26
+ }
27
+
28
+ export interface StakingParams {
29
+ delegatorAddress: Address
30
+ validatorShareAddress: Address
31
+ amount: string
32
+ maximumSharesToBurn?: bigint
33
+ staker: PolygonStaker
34
+ walletClient: WalletClient
35
+ publicClient: PublicClient
36
+ }
37
+
38
+ export const prepareTests = async (): Promise<TestSetup> => {
39
+ const privateKey = networkConfig.accounts[0].privateKey as Hex
40
+ const account = privateKeyToAccount(privateKey)
41
+
42
+ const walletClient = createWalletClient({
43
+ account,
44
+ chain: hardhat,
45
+ transport: http()
46
+ })
47
+
48
+ const publicClient = createPublicClient({
49
+ chain: hardhat,
50
+ transport: http()
51
+ })
52
+
53
+ const staker = new PolygonStaker({
54
+ network: 'mainnet',
55
+ rpcUrl: hardhat.rpcUrls.default.http[0]
56
+ })
57
+
58
+ return {
59
+ validatorShareAddress: CHORUS_ONE_POLYGON_VALIDATORS.mainnet,
60
+ walletClient,
61
+ publicClient,
62
+ staker,
63
+ delegatorAddress: account.address
64
+ }
65
+ }
66
+
67
+ export const fundWithStakingToken = async ({
68
+ publicClient,
69
+ recipientAddress,
70
+ amount
71
+ }: {
72
+ publicClient: PublicClient
73
+ recipientAddress: Address
74
+ amount: bigint
75
+ }): Promise<void> => {
76
+ await impersonate({ publicClient, address: NETWORK_CONTRACTS.mainnet.stakeManagerAddress })
77
+
78
+ const impersonatedClient = createWalletClient({
79
+ account: NETWORK_CONTRACTS.mainnet.stakeManagerAddress,
80
+ chain: hardhat,
81
+ transport: http()
82
+ })
83
+
84
+ await sendTx({
85
+ tx: {
86
+ to: NETWORK_CONTRACTS.mainnet.stakingTokenAddress,
87
+ data: encodeFunctionData({
88
+ abi: erc20Abi,
89
+ functionName: 'transfer',
90
+ args: [recipientAddress, amount]
91
+ }),
92
+ value: 0n
93
+ },
94
+ walletClient: impersonatedClient,
95
+ publicClient,
96
+ senderAddress: NETWORK_CONTRACTS.mainnet.stakeManagerAddress
97
+ })
98
+ }
99
+
100
+ export const approve = async ({
101
+ delegatorAddress,
102
+ amount,
103
+ staker,
104
+ walletClient,
105
+ publicClient
106
+ }: Omit<StakingParams, 'validatorShareAddress'>): Promise<void> => {
107
+ const { tx } = await staker.buildApproveTx({ amount })
108
+ await sendTx({ tx, walletClient, publicClient, senderAddress: delegatorAddress })
109
+ }
110
+
111
+ export const stake = async ({
112
+ delegatorAddress,
113
+ validatorShareAddress,
114
+ amount,
115
+ staker,
116
+ walletClient,
117
+ publicClient
118
+ }: StakingParams): Promise<void> => {
119
+ const { tx } = await staker.buildStakeTx({ delegatorAddress, validatorShareAddress, amount, minSharesToMint: 0n })
120
+ await sendTx({ tx, walletClient, publicClient, senderAddress: delegatorAddress })
121
+ }
122
+
123
+ export const approveAndStake = async (params: StakingParams): Promise<void> => {
124
+ await approve(params)
125
+ await stake(params)
126
+ }
127
+
128
+ export const sendTx = async ({
129
+ tx,
130
+ walletClient,
131
+ publicClient,
132
+ senderAddress
133
+ }: {
134
+ tx: Transaction
135
+ walletClient: WalletClient
136
+ publicClient: PublicClient
137
+ senderAddress: Address
138
+ }): Promise<void> => {
139
+ const request = await walletClient.prepareTransactionRequest({
140
+ ...tx,
141
+ chain: undefined
142
+ })
143
+
144
+ const hash = await walletClient.sendTransaction({
145
+ ...request,
146
+ account: senderAddress
147
+ })
148
+
149
+ const receipt = await publicClient.getTransactionReceipt({ hash })
150
+ assert.equal(receipt.status, 'success')
151
+ }
152
+
153
+ export const unstake = async ({
154
+ delegatorAddress,
155
+ validatorShareAddress,
156
+ amount,
157
+ maximumSharesToBurn,
158
+ staker,
159
+ walletClient,
160
+ publicClient
161
+ }: Required<StakingParams>): Promise<void> => {
162
+ const { tx } = await staker.buildUnstakeTx({ delegatorAddress, validatorShareAddress, amount, maximumSharesToBurn })
163
+ await sendTx({ tx, walletClient, publicClient, senderAddress: delegatorAddress })
164
+ }
165
+
166
+ export const getStakingTokenBalance = async ({
167
+ publicClient,
168
+ address
169
+ }: {
170
+ publicClient: PublicClient
171
+ address: Address
172
+ }): Promise<bigint> => {
173
+ return publicClient.readContract({
174
+ address: NETWORK_CONTRACTS.mainnet.stakingTokenAddress,
175
+ abi: erc20Abi,
176
+ functionName: 'balanceOf',
177
+ args: [address]
178
+ })
179
+ }
180
+
181
+ export const getWithdrawalDelay = async ({ publicClient }: { publicClient: PublicClient }): Promise<bigint> => {
182
+ return publicClient.readContract({
183
+ address: NETWORK_CONTRACTS.mainnet.stakeManagerAddress,
184
+ abi: [
185
+ {
186
+ type: 'function',
187
+ name: 'withdrawalDelay',
188
+ inputs: [],
189
+ outputs: [{ name: '', type: 'uint256' }],
190
+ stateMutability: 'view'
191
+ }
192
+ ] as const,
193
+ functionName: 'withdrawalDelay'
194
+ })
195
+ }
196
+
197
+ export const impersonate = async ({
198
+ publicClient,
199
+ address
200
+ }: {
201
+ publicClient: PublicClient
202
+ address: Address
203
+ }): Promise<void> => {
204
+ await publicClient.request({
205
+ method: 'hardhat_impersonateAccount',
206
+ params: [address]
207
+ } as any)
208
+
209
+ await publicClient.request({
210
+ method: 'hardhat_setBalance',
211
+ params: [address, toHex(parseEther('10'))]
212
+ } as any)
213
+ }
214
+
215
+ // Reference: https://etherscan.io/address/0x6e7a5820baD6cebA8Ef5ea69c0C92EbbDAc9CE48
216
+ const GOVERNANCE_ADDRESS = '0x6e7a5820baD6cebA8Ef5ea69c0C92EbbDAc9CE48' as Address
217
+
218
+ // Reference: https://github.com/0xPolygon/pos-contracts/blob/main/contracts/staking/stakeManager/StakeManager.sol
219
+ const SET_CURRENT_EPOCH_ABI = [
220
+ {
221
+ type: 'function',
222
+ name: 'setCurrentEpoch',
223
+ inputs: [{ name: '_currentEpoch', type: 'uint256' }],
224
+ outputs: [],
225
+ stateMutability: 'nonpayable'
226
+ }
227
+ ] as const
228
+
229
+ export const advanceEpoch = async ({
230
+ publicClient,
231
+ staker,
232
+ targetEpoch
233
+ }: {
234
+ publicClient: PublicClient
235
+ staker: PolygonStaker
236
+ targetEpoch: bigint
237
+ }): Promise<void> => {
238
+ const currentEpoch = await staker.getEpoch()
239
+ if (currentEpoch >= targetEpoch) return
240
+
241
+ await impersonate({ publicClient, address: GOVERNANCE_ADDRESS })
242
+
243
+ const governanceWallet = createWalletClient({
244
+ account: GOVERNANCE_ADDRESS,
245
+ chain: hardhat,
246
+ transport: http()
247
+ })
248
+
249
+ await sendTx({
250
+ tx: {
251
+ to: NETWORK_CONTRACTS.mainnet.stakeManagerAddress,
252
+ data: encodeFunctionData({
253
+ abi: SET_CURRENT_EPOCH_ABI,
254
+ functionName: 'setCurrentEpoch',
255
+ args: [targetEpoch]
256
+ }),
257
+ value: 0n
258
+ },
259
+ walletClient: governanceWallet,
260
+ publicClient,
261
+ senderAddress: GOVERNANCE_ADDRESS
262
+ })
263
+ }
@@ -0,0 +1,14 @@
1
+ {
2
+ "networks": {
3
+ "ethereum": {
4
+ "name": "ethereum",
5
+ "url": "https://ethereum-rpc.publicnode.com"
6
+ }
7
+ },
8
+ "accounts": [
9
+ {
10
+ "privateKey": "0x689af8efa8c651a91ad287602527f3af2fe9f6501a7ac4b061667b5a93e037fd",
11
+ "balance": "10000000000000000000000"
12
+ }
13
+ ]
14
+ }
@@ -0,0 +1,154 @@
1
+ import { PolygonStaker } from '../src/staker'
2
+ import { NETWORK_CONTRACTS } from '../src/constants'
3
+ import { describe, it, beforeEach } from 'mocha'
4
+ import { use, expect, assert } from 'chai'
5
+ import chaiAsPromised from 'chai-as-promised'
6
+ import { type Address, maxUint256, encodeFunctionData, erc20Abi } from 'viem'
7
+ import { EXPECTED_APPROVE_TX, TEST_ADDRESS, TEST_VALIDATOR_SHARE } from './fixtures/expected-data'
8
+
9
+ use(chaiAsPromised)
10
+
11
+ describe('PolygonStaker', () => {
12
+ let staker: PolygonStaker
13
+
14
+ beforeEach(() => {
15
+ staker = new PolygonStaker({
16
+ network: 'mainnet',
17
+ rpcUrl: 'https://ethereum-rpc.publicnode.com'
18
+ })
19
+ })
20
+
21
+ describe('buildApproveTx', () => {
22
+ it('should generate correct unsigned approve tx', async () => {
23
+ const { tx } = await staker.buildApproveTx({
24
+ amount: EXPECTED_APPROVE_TX.amount
25
+ })
26
+
27
+ assert.equal(tx.to, EXPECTED_APPROVE_TX.expected.to)
28
+ assert.equal(tx.data, EXPECTED_APPROVE_TX.expected.data)
29
+ assert.equal(tx.value, EXPECTED_APPROVE_TX.expected.value)
30
+ })
31
+
32
+ it('should generate correct unsigned approve tx for max (unlimited) amount', async () => {
33
+ const { tx } = await staker.buildApproveTx({ amount: 'max' })
34
+
35
+ const expectedData = encodeFunctionData({
36
+ abi: erc20Abi,
37
+ functionName: 'approve',
38
+ args: [NETWORK_CONTRACTS.mainnet.stakeManagerAddress, maxUint256]
39
+ })
40
+
41
+ assert.equal(tx.to, EXPECTED_APPROVE_TX.expected.to)
42
+ assert.equal(tx.data, expectedData)
43
+ assert.equal(tx.value, EXPECTED_APPROVE_TX.expected.value)
44
+ })
45
+
46
+ it('should reject invalid amounts', async () => {
47
+ await expect(staker.buildApproveTx({ amount: '0' })).to.be.rejectedWith('Amount must be greater than 0')
48
+ await expect(staker.buildApproveTx({ amount: '' })).to.be.rejectedWith('Amount cannot be empty')
49
+ await expect(staker.buildApproveTx({ amount: 'invalid' })).to.be.rejectedWith('Amount must be a valid number')
50
+ })
51
+ })
52
+
53
+ describe('address validation', () => {
54
+ it('should reject invalid delegator address in buildStakeTx', async () => {
55
+ await expect(
56
+ staker.buildStakeTx({
57
+ delegatorAddress: 'invalid' as Address,
58
+ validatorShareAddress: TEST_VALIDATOR_SHARE,
59
+ amount: '100',
60
+ minSharesToMint: 0n
61
+ })
62
+ ).to.be.rejectedWith('Invalid delegator address')
63
+ })
64
+
65
+ it('should reject invalid validator share address in buildStakeTx', async () => {
66
+ await expect(
67
+ staker.buildStakeTx({
68
+ delegatorAddress: TEST_ADDRESS,
69
+ validatorShareAddress: 'invalid' as Address,
70
+ amount: '100',
71
+ minSharesToMint: 0n
72
+ })
73
+ ).to.be.rejectedWith('Invalid validator share address')
74
+ })
75
+
76
+ it('should reject invalid delegator address in buildUnstakeTx', async () => {
77
+ await expect(
78
+ staker.buildUnstakeTx({
79
+ delegatorAddress: 'invalid' as Address,
80
+ validatorShareAddress: TEST_VALIDATOR_SHARE,
81
+ amount: '100',
82
+ maximumSharesToBurn: 0n
83
+ })
84
+ ).to.be.rejectedWith('Invalid delegator address')
85
+ })
86
+
87
+ it('should reject invalid validator share address in buildUnstakeTx', async () => {
88
+ await expect(
89
+ staker.buildUnstakeTx({
90
+ delegatorAddress: TEST_ADDRESS,
91
+ validatorShareAddress: 'invalid' as Address,
92
+ amount: '100',
93
+ maximumSharesToBurn: 0n
94
+ })
95
+ ).to.be.rejectedWith('Invalid validator share address')
96
+ })
97
+ })
98
+
99
+ describe('buildStakeTx slippage validation', () => {
100
+ it('should reject when both slippageBps and minSharesToMint are provided', async () => {
101
+ await expect(
102
+ staker.buildStakeTx({
103
+ delegatorAddress: TEST_ADDRESS,
104
+ validatorShareAddress: TEST_VALIDATOR_SHARE,
105
+ amount: '100',
106
+ slippageBps: 50,
107
+ minSharesToMint: 100n
108
+ })
109
+ ).to.be.rejectedWith('Cannot specify both slippageBps and minSharesToMint. Use one or the other.')
110
+ })
111
+ })
112
+
113
+ describe('buildUnstakeTx slippage validation', () => {
114
+ it('should reject when both slippageBps and maximumSharesToBurn are provided', async () => {
115
+ await expect(
116
+ staker.buildUnstakeTx({
117
+ delegatorAddress: TEST_ADDRESS,
118
+ validatorShareAddress: TEST_VALIDATOR_SHARE,
119
+ amount: '100',
120
+ slippageBps: 50,
121
+ maximumSharesToBurn: 100n
122
+ })
123
+ ).to.be.rejectedWith('Cannot specify both slippageBps and maximumSharesToBurn. Use one or the other.')
124
+ })
125
+ })
126
+
127
+ describe('getUnbonds', () => {
128
+ it('should return empty array for empty nonces input', async () => {
129
+ const result = await staker.getUnbonds({
130
+ delegatorAddress: TEST_ADDRESS,
131
+ validatorShareAddress: TEST_VALIDATOR_SHARE,
132
+ unbondNonces: []
133
+ })
134
+
135
+ assert.isArray(result)
136
+ assert.lengthOf(result, 0)
137
+ })
138
+ })
139
+
140
+ describe('getAddressDerivationFn', () => {
141
+ it('should derive correct ethereum address from a compressed public key', async () => {
142
+ const fn = PolygonStaker.getAddressDerivationFn()
143
+
144
+ // Known secp256k1 compressed public key (generator point)
145
+ const compressedPubKey = Uint8Array.from(
146
+ Buffer.from('0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798', 'hex')
147
+ )
148
+
149
+ const [address] = await fn(compressedPubKey)
150
+ assert.isString(address)
151
+ assert.equal(address.length, 40)
152
+ })
153
+ })
154
+ })
@@ -0,0 +1,9 @@
1
+ {
2
+ "extends": "../../tsconfig.cjs.json",
3
+ "compilerOptions": {
4
+ "rootDir": "src"
5
+ },
6
+ "include": ["src"],
7
+ "exclude": ["node_modules", "dist"],
8
+ "references": [{ "path": "../signer" }]
9
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,13 @@
1
+ {
2
+ "extends": "../../tsconfig.base.json",
3
+ "compilerOptions": {
4
+ "rootDir": "src",
5
+ "baseUrl": ".",
6
+ "paths": {
7
+ "@chorus-one/signer": ["../signer/src"]
8
+ }
9
+ },
10
+ "include": ["src"],
11
+ "exclude": ["node_modules", "dist"],
12
+ "references": [{ "path": "../signer" }]
13
+ }
@@ -0,0 +1,9 @@
1
+ {
2
+ "extends": "../../tsconfig.mjs.json",
3
+ "compilerOptions": {
4
+ "rootDir": "src"
5
+ },
6
+ "include": ["src"],
7
+ "exclude": ["node_modules", "dist"],
8
+ "references": [{ "path": "../signer" }]
9
+ }