@flatcash/bearerswap 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.
- package/README.md +142 -0
- package/dist/index.d.mts +147 -0
- package/dist/index.d.ts +147 -0
- package/dist/index.js +218 -0
- package/dist/index.mjs +191 -0
- package/package.json +35 -0
package/README.md
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
# @flatcash/bearerswap
|
|
2
|
+
|
|
3
|
+
**Private token transfers on Ethereum.** Send any ERC-20 token without revealing sender-recipient links on-chain.
|
|
4
|
+
|
|
5
|
+
BearerSwap uses a commit-reveal pattern with a privacy relayer that adds timing randomization, breaking the correlation between deposit and withdrawal.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install @flatcash/bearerswap ethers
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Quick Start
|
|
14
|
+
|
|
15
|
+
```typescript
|
|
16
|
+
import { BearerSwap } from '@flatcash/bearerswap';
|
|
17
|
+
|
|
18
|
+
// Initialize with your private key (sender)
|
|
19
|
+
const bs = new BearerSwap({
|
|
20
|
+
privateKey: process.env.PRIVATE_KEY,
|
|
21
|
+
rpcUrl: 'https://eth.drpc.org',
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
// 1. Commit tokens (locks them in the contract)
|
|
25
|
+
const { secret, nonce, txHash } = await bs.commit(
|
|
26
|
+
'0x853d955aCEf822Db058eb8505911ED77F175b99e', // FLAT token
|
|
27
|
+
'100.0', // amount
|
|
28
|
+
'0xRecipientAddress...' // recipient
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
console.log(`Committed! TX: ${txHash}`);
|
|
32
|
+
console.log(`Share these with recipient: secret=${secret}, nonce=${nonce}`);
|
|
33
|
+
|
|
34
|
+
// 2. Deliver (recipient or anyone calls this)
|
|
35
|
+
const delivery = await bs.deliver(secret, recipientAddress, nonce);
|
|
36
|
+
console.log(`Delivery queued! ETA: ${delivery.estimatedDeliveryMinutes} min`);
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## How It Works
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
Sender Contract Relayer Recipient
|
|
43
|
+
| | | |
|
|
44
|
+
|-- commit(hash, token) -->| | |
|
|
45
|
+
| (locks tokens + ETH) | | |
|
|
46
|
+
| | | |
|
|
47
|
+
|--- share secret+nonce ---|------------------------|------> (off-chain) --->|
|
|
48
|
+
| | | |
|
|
49
|
+
| | |<-- deliver(s,r,n) -----|
|
|
50
|
+
| | | |
|
|
51
|
+
| | (random 2-45 min) | |
|
|
52
|
+
| | | |
|
|
53
|
+
| |<--- reveal(s,r,n) -----| |
|
|
54
|
+
| |--- tokens + ETH -------|----------------------->|
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
**Privacy guarantees:**
|
|
58
|
+
- On-chain, the commit contains only a hash — no recipient info
|
|
59
|
+
- The relayer adds a random delay (2–45 min, exponential distribution)
|
|
60
|
+
- The recipient receives tokens + a small ETH stipend for gas
|
|
61
|
+
- No link between sender and recipient is visible on-chain
|
|
62
|
+
|
|
63
|
+
## API Reference
|
|
64
|
+
|
|
65
|
+
### `new BearerSwap(config)`
|
|
66
|
+
|
|
67
|
+
| Option | Type | Default | Description |
|
|
68
|
+
|--------|------|---------|-------------|
|
|
69
|
+
| `relayerUrl` | string | `https://flat.cash` | Relayer API URL |
|
|
70
|
+
| `rpcUrl` | string | `https://eth.drpc.org` | Ethereum RPC endpoint |
|
|
71
|
+
| `privateKey` | string | — | Sender's private key |
|
|
72
|
+
| `provider` | ethers.Provider | — | Custom provider |
|
|
73
|
+
| `signer` | ethers.Signer | — | Custom signer |
|
|
74
|
+
|
|
75
|
+
### `bs.commit(token, amount, recipient, decimals?)`
|
|
76
|
+
|
|
77
|
+
Locks tokens in the BearerSwap contract. Returns `{ secret, nonce, commitHash, txHash }`.
|
|
78
|
+
|
|
79
|
+
### `bs.deliver(secret, recipient, nonce)`
|
|
80
|
+
|
|
81
|
+
Queues the reveal via the relayer. Returns `{ success, estimatedDeliveryMinutes, flatAmount }`.
|
|
82
|
+
|
|
83
|
+
### `bs.status()`
|
|
84
|
+
|
|
85
|
+
Returns relayer health: balance, queue size, availability.
|
|
86
|
+
|
|
87
|
+
### `bs.resolve(identifier)`
|
|
88
|
+
|
|
89
|
+
Resolves a FlatID username or ENS name to an Ethereum address.
|
|
90
|
+
|
|
91
|
+
### `BearerSwap.computeHash(secret, recipient, nonce)`
|
|
92
|
+
|
|
93
|
+
Static helper to compute the commit hash for verification.
|
|
94
|
+
|
|
95
|
+
## Use Cases
|
|
96
|
+
|
|
97
|
+
### AI Agent Payments
|
|
98
|
+
```typescript
|
|
99
|
+
// Your autonomous agent pays for services privately
|
|
100
|
+
const bs = new BearerSwap({ privateKey: AGENT_WALLET_KEY });
|
|
101
|
+
const { secret, nonce } = await bs.commit(FLAT_TOKEN, '10.0', serviceProvider);
|
|
102
|
+
// Agent shares secret with service provider via API
|
|
103
|
+
await fetch(serviceProviderUrl, { body: JSON.stringify({ secret, nonce }) });
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### Private Payroll
|
|
107
|
+
```typescript
|
|
108
|
+
// Pay employees without revealing individual salaries on-chain
|
|
109
|
+
for (const employee of employees) {
|
|
110
|
+
const { secret, nonce } = await bs.commit(FLAT_TOKEN, employee.salary, employee.address);
|
|
111
|
+
await sendEncryptedMessage(employee.email, { secret, nonce });
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### Tipping / Donations
|
|
116
|
+
```typescript
|
|
117
|
+
// Anonymous tips to content creators
|
|
118
|
+
const { secret, nonce } = await bs.commit(FLAT_TOKEN, '5.0', creatorAddress);
|
|
119
|
+
// Share via any private channel
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## Supported Tokens
|
|
123
|
+
|
|
124
|
+
Any ERC-20 token on Ethereum mainnet. Primary tokens:
|
|
125
|
+
- **FLAT** (`0x853d955aCEf822Db058eb8505911ED77F175b99e`) — CPI-pegged stablecoin
|
|
126
|
+
- **SAVE** — Locked FLAT with yield
|
|
127
|
+
|
|
128
|
+
## Contract
|
|
129
|
+
|
|
130
|
+
- **BearerSwap V3:** `0x5de315Dab49012c5bbeC41d7a3B25c6829a3e566`
|
|
131
|
+
- **Network:** Ethereum Mainnet
|
|
132
|
+
- **Verified on Etherscan:** [View Contract](https://etherscan.io/address/0x5de315Dab49012c5bbeC41d7a3B25c6829a3e566)
|
|
133
|
+
|
|
134
|
+
## Fees
|
|
135
|
+
|
|
136
|
+
- **Protocol fee:** 0 (no fees extracted)
|
|
137
|
+
- **Gas:** Sender pays commit gas + ETH stipend (~0.0004 ETH)
|
|
138
|
+
- **Relayer:** Free — operated by the FLAT Protocol
|
|
139
|
+
|
|
140
|
+
## License
|
|
141
|
+
|
|
142
|
+
MIT — Flat Protocol team
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { ethers } from 'ethers';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @flatcash/bearerswap — Private token transfers on Ethereum
|
|
5
|
+
*
|
|
6
|
+
* BearerSwap lets you send ERC-20 tokens privately using a commit-reveal
|
|
7
|
+
* pattern with a relayer that adds timing randomization for privacy.
|
|
8
|
+
*
|
|
9
|
+
* Usage:
|
|
10
|
+
* import { BearerSwap } from '@flatcash/bearerswap';
|
|
11
|
+
* const bs = new BearerSwap({ relayerUrl: 'https://flat.cash' });
|
|
12
|
+
* const { secret, nonce, txHash } = await bs.commit(token, amount, recipient);
|
|
13
|
+
* // Share secret + nonce + recipient with the receiver (off-chain)
|
|
14
|
+
* const delivery = await bs.deliver(secret, recipient, nonce);
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
interface BearerSwapConfig {
|
|
18
|
+
/** Relayer API base URL (default: https://flat.cash) */
|
|
19
|
+
relayerUrl?: string;
|
|
20
|
+
/** Ethereum RPC URL for on-chain operations */
|
|
21
|
+
rpcUrl?: string;
|
|
22
|
+
/** Private key for signing commit transactions (sender) */
|
|
23
|
+
privateKey?: string;
|
|
24
|
+
/** Ethers provider (alternative to rpcUrl) */
|
|
25
|
+
provider?: ethers.Provider;
|
|
26
|
+
/** Ethers signer (alternative to privateKey + provider) */
|
|
27
|
+
signer?: ethers.Signer;
|
|
28
|
+
}
|
|
29
|
+
interface CommitResult {
|
|
30
|
+
/** The secret (bytes32) — share with recipient off-chain */
|
|
31
|
+
secret: string;
|
|
32
|
+
/** The nonce (bytes32) — share with recipient off-chain */
|
|
33
|
+
nonce: string;
|
|
34
|
+
/** The commit hash stored on-chain */
|
|
35
|
+
commitHash: string;
|
|
36
|
+
/** Transaction hash of the commit */
|
|
37
|
+
txHash: string;
|
|
38
|
+
/** Amount committed (human-readable) */
|
|
39
|
+
amount: string;
|
|
40
|
+
/** Token address */
|
|
41
|
+
token: string;
|
|
42
|
+
/** Recipient address */
|
|
43
|
+
recipient: string;
|
|
44
|
+
}
|
|
45
|
+
interface DeliverResult {
|
|
46
|
+
/** Whether the delivery was queued successfully */
|
|
47
|
+
success: boolean;
|
|
48
|
+
/** Current status */
|
|
49
|
+
status: "queued" | "already_settled";
|
|
50
|
+
/** Estimated delivery time in minutes (privacy delay) */
|
|
51
|
+
estimatedDeliveryMinutes: number;
|
|
52
|
+
/** Amount being delivered (human-readable) */
|
|
53
|
+
flatAmount: string;
|
|
54
|
+
/** Recipient address */
|
|
55
|
+
recipient: string;
|
|
56
|
+
/** Commit hash */
|
|
57
|
+
hash: string;
|
|
58
|
+
}
|
|
59
|
+
interface RelayerStatus {
|
|
60
|
+
/** BearerSwap contract address */
|
|
61
|
+
contract: string;
|
|
62
|
+
/** Contract version */
|
|
63
|
+
version: string;
|
|
64
|
+
/** Number of reveals pending in queue */
|
|
65
|
+
pendingInQueue: number;
|
|
66
|
+
/** ETH stipend sent with each reveal */
|
|
67
|
+
recipientStipend: string;
|
|
68
|
+
/** Relayer wallet address */
|
|
69
|
+
relayerAddress?: string;
|
|
70
|
+
/** Relayer ETH balance */
|
|
71
|
+
relayerBalanceEth?: string;
|
|
72
|
+
/** Whether the contract is paused */
|
|
73
|
+
contractPaused?: boolean;
|
|
74
|
+
/** Whether the relayer is available */
|
|
75
|
+
available?: boolean;
|
|
76
|
+
}
|
|
77
|
+
interface ResolveResult {
|
|
78
|
+
/** Resolved Ethereum address */
|
|
79
|
+
address: string;
|
|
80
|
+
/** Type of identifier resolved */
|
|
81
|
+
type: "address" | "ens" | "flatid";
|
|
82
|
+
/** Display name (username or ENS) */
|
|
83
|
+
displayName: string | null;
|
|
84
|
+
}
|
|
85
|
+
declare const BEARERSWAP_V3_ADDRESS = "0x5de315Dab49012c5bbeC41d7a3B25c6829a3e566";
|
|
86
|
+
declare const BEARERSWAP_V3_ABI: string[];
|
|
87
|
+
declare class BearerSwap {
|
|
88
|
+
private relayerUrl;
|
|
89
|
+
private provider;
|
|
90
|
+
private signer;
|
|
91
|
+
constructor(config?: BearerSwapConfig);
|
|
92
|
+
/** Contract address */
|
|
93
|
+
get contractAddress(): string;
|
|
94
|
+
/**
|
|
95
|
+
* Commit tokens on-chain for private transfer.
|
|
96
|
+
*
|
|
97
|
+
* This locks tokens in the BearerSwap contract. The returned secret and
|
|
98
|
+
* nonce must be shared with the recipient off-chain (e.g., via encrypted
|
|
99
|
+
* message, QR code, or any private channel).
|
|
100
|
+
*
|
|
101
|
+
* @param token - ERC-20 token address
|
|
102
|
+
* @param amount - Amount to send (human-readable, e.g., "100.0")
|
|
103
|
+
* @param recipient - Recipient Ethereum address
|
|
104
|
+
* @param decimals - Token decimals (default: 18)
|
|
105
|
+
*/
|
|
106
|
+
commit(token: string, amount: string, recipient: string, decimals?: number): Promise<CommitResult>;
|
|
107
|
+
/**
|
|
108
|
+
* Deliver a committed transfer to the recipient via the relayer.
|
|
109
|
+
*
|
|
110
|
+
* The relayer adds a random privacy delay (2–45 min) before executing
|
|
111
|
+
* the on-chain reveal, breaking timing correlation between commit and reveal.
|
|
112
|
+
*
|
|
113
|
+
* @param secret - The secret from the commit step
|
|
114
|
+
* @param recipient - The recipient address
|
|
115
|
+
* @param nonce - The nonce from the commit step
|
|
116
|
+
*/
|
|
117
|
+
deliver(secret: string, recipient: string, nonce: string): Promise<DeliverResult>;
|
|
118
|
+
/**
|
|
119
|
+
* Check relayer status (balance, queue size, availability).
|
|
120
|
+
*/
|
|
121
|
+
status(): Promise<RelayerStatus>;
|
|
122
|
+
/**
|
|
123
|
+
* Resolve a FlatID username or ENS name to an Ethereum address.
|
|
124
|
+
*
|
|
125
|
+
* @param identifier - FlatID username, ENS name, or Ethereum address
|
|
126
|
+
*/
|
|
127
|
+
resolve(identifier: string): Promise<ResolveResult>;
|
|
128
|
+
/**
|
|
129
|
+
* Check the status of a specific commitment on-chain.
|
|
130
|
+
*
|
|
131
|
+
* @param commitHash - The commit hash (bytes32)
|
|
132
|
+
*/
|
|
133
|
+
getCommitment(commitHash: string): Promise<{
|
|
134
|
+
sender: string;
|
|
135
|
+
token: string;
|
|
136
|
+
amount: bigint;
|
|
137
|
+
timestamp: bigint;
|
|
138
|
+
settled: boolean;
|
|
139
|
+
}>;
|
|
140
|
+
/**
|
|
141
|
+
* Compute the commit hash from secret, recipient, and nonce.
|
|
142
|
+
* Useful for verifying parameters before delivery.
|
|
143
|
+
*/
|
|
144
|
+
static computeHash(secret: string, recipient: string, nonce: string): string;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
export { BEARERSWAP_V3_ABI, BEARERSWAP_V3_ADDRESS, BearerSwap, type BearerSwapConfig, type CommitResult, type DeliverResult, type RelayerStatus, type ResolveResult, BearerSwap as default };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { ethers } from 'ethers';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @flatcash/bearerswap — Private token transfers on Ethereum
|
|
5
|
+
*
|
|
6
|
+
* BearerSwap lets you send ERC-20 tokens privately using a commit-reveal
|
|
7
|
+
* pattern with a relayer that adds timing randomization for privacy.
|
|
8
|
+
*
|
|
9
|
+
* Usage:
|
|
10
|
+
* import { BearerSwap } from '@flatcash/bearerswap';
|
|
11
|
+
* const bs = new BearerSwap({ relayerUrl: 'https://flat.cash' });
|
|
12
|
+
* const { secret, nonce, txHash } = await bs.commit(token, amount, recipient);
|
|
13
|
+
* // Share secret + nonce + recipient with the receiver (off-chain)
|
|
14
|
+
* const delivery = await bs.deliver(secret, recipient, nonce);
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
interface BearerSwapConfig {
|
|
18
|
+
/** Relayer API base URL (default: https://flat.cash) */
|
|
19
|
+
relayerUrl?: string;
|
|
20
|
+
/** Ethereum RPC URL for on-chain operations */
|
|
21
|
+
rpcUrl?: string;
|
|
22
|
+
/** Private key for signing commit transactions (sender) */
|
|
23
|
+
privateKey?: string;
|
|
24
|
+
/** Ethers provider (alternative to rpcUrl) */
|
|
25
|
+
provider?: ethers.Provider;
|
|
26
|
+
/** Ethers signer (alternative to privateKey + provider) */
|
|
27
|
+
signer?: ethers.Signer;
|
|
28
|
+
}
|
|
29
|
+
interface CommitResult {
|
|
30
|
+
/** The secret (bytes32) — share with recipient off-chain */
|
|
31
|
+
secret: string;
|
|
32
|
+
/** The nonce (bytes32) — share with recipient off-chain */
|
|
33
|
+
nonce: string;
|
|
34
|
+
/** The commit hash stored on-chain */
|
|
35
|
+
commitHash: string;
|
|
36
|
+
/** Transaction hash of the commit */
|
|
37
|
+
txHash: string;
|
|
38
|
+
/** Amount committed (human-readable) */
|
|
39
|
+
amount: string;
|
|
40
|
+
/** Token address */
|
|
41
|
+
token: string;
|
|
42
|
+
/** Recipient address */
|
|
43
|
+
recipient: string;
|
|
44
|
+
}
|
|
45
|
+
interface DeliverResult {
|
|
46
|
+
/** Whether the delivery was queued successfully */
|
|
47
|
+
success: boolean;
|
|
48
|
+
/** Current status */
|
|
49
|
+
status: "queued" | "already_settled";
|
|
50
|
+
/** Estimated delivery time in minutes (privacy delay) */
|
|
51
|
+
estimatedDeliveryMinutes: number;
|
|
52
|
+
/** Amount being delivered (human-readable) */
|
|
53
|
+
flatAmount: string;
|
|
54
|
+
/** Recipient address */
|
|
55
|
+
recipient: string;
|
|
56
|
+
/** Commit hash */
|
|
57
|
+
hash: string;
|
|
58
|
+
}
|
|
59
|
+
interface RelayerStatus {
|
|
60
|
+
/** BearerSwap contract address */
|
|
61
|
+
contract: string;
|
|
62
|
+
/** Contract version */
|
|
63
|
+
version: string;
|
|
64
|
+
/** Number of reveals pending in queue */
|
|
65
|
+
pendingInQueue: number;
|
|
66
|
+
/** ETH stipend sent with each reveal */
|
|
67
|
+
recipientStipend: string;
|
|
68
|
+
/** Relayer wallet address */
|
|
69
|
+
relayerAddress?: string;
|
|
70
|
+
/** Relayer ETH balance */
|
|
71
|
+
relayerBalanceEth?: string;
|
|
72
|
+
/** Whether the contract is paused */
|
|
73
|
+
contractPaused?: boolean;
|
|
74
|
+
/** Whether the relayer is available */
|
|
75
|
+
available?: boolean;
|
|
76
|
+
}
|
|
77
|
+
interface ResolveResult {
|
|
78
|
+
/** Resolved Ethereum address */
|
|
79
|
+
address: string;
|
|
80
|
+
/** Type of identifier resolved */
|
|
81
|
+
type: "address" | "ens" | "flatid";
|
|
82
|
+
/** Display name (username or ENS) */
|
|
83
|
+
displayName: string | null;
|
|
84
|
+
}
|
|
85
|
+
declare const BEARERSWAP_V3_ADDRESS = "0x5de315Dab49012c5bbeC41d7a3B25c6829a3e566";
|
|
86
|
+
declare const BEARERSWAP_V3_ABI: string[];
|
|
87
|
+
declare class BearerSwap {
|
|
88
|
+
private relayerUrl;
|
|
89
|
+
private provider;
|
|
90
|
+
private signer;
|
|
91
|
+
constructor(config?: BearerSwapConfig);
|
|
92
|
+
/** Contract address */
|
|
93
|
+
get contractAddress(): string;
|
|
94
|
+
/**
|
|
95
|
+
* Commit tokens on-chain for private transfer.
|
|
96
|
+
*
|
|
97
|
+
* This locks tokens in the BearerSwap contract. The returned secret and
|
|
98
|
+
* nonce must be shared with the recipient off-chain (e.g., via encrypted
|
|
99
|
+
* message, QR code, or any private channel).
|
|
100
|
+
*
|
|
101
|
+
* @param token - ERC-20 token address
|
|
102
|
+
* @param amount - Amount to send (human-readable, e.g., "100.0")
|
|
103
|
+
* @param recipient - Recipient Ethereum address
|
|
104
|
+
* @param decimals - Token decimals (default: 18)
|
|
105
|
+
*/
|
|
106
|
+
commit(token: string, amount: string, recipient: string, decimals?: number): Promise<CommitResult>;
|
|
107
|
+
/**
|
|
108
|
+
* Deliver a committed transfer to the recipient via the relayer.
|
|
109
|
+
*
|
|
110
|
+
* The relayer adds a random privacy delay (2–45 min) before executing
|
|
111
|
+
* the on-chain reveal, breaking timing correlation between commit and reveal.
|
|
112
|
+
*
|
|
113
|
+
* @param secret - The secret from the commit step
|
|
114
|
+
* @param recipient - The recipient address
|
|
115
|
+
* @param nonce - The nonce from the commit step
|
|
116
|
+
*/
|
|
117
|
+
deliver(secret: string, recipient: string, nonce: string): Promise<DeliverResult>;
|
|
118
|
+
/**
|
|
119
|
+
* Check relayer status (balance, queue size, availability).
|
|
120
|
+
*/
|
|
121
|
+
status(): Promise<RelayerStatus>;
|
|
122
|
+
/**
|
|
123
|
+
* Resolve a FlatID username or ENS name to an Ethereum address.
|
|
124
|
+
*
|
|
125
|
+
* @param identifier - FlatID username, ENS name, or Ethereum address
|
|
126
|
+
*/
|
|
127
|
+
resolve(identifier: string): Promise<ResolveResult>;
|
|
128
|
+
/**
|
|
129
|
+
* Check the status of a specific commitment on-chain.
|
|
130
|
+
*
|
|
131
|
+
* @param commitHash - The commit hash (bytes32)
|
|
132
|
+
*/
|
|
133
|
+
getCommitment(commitHash: string): Promise<{
|
|
134
|
+
sender: string;
|
|
135
|
+
token: string;
|
|
136
|
+
amount: bigint;
|
|
137
|
+
timestamp: bigint;
|
|
138
|
+
settled: boolean;
|
|
139
|
+
}>;
|
|
140
|
+
/**
|
|
141
|
+
* Compute the commit hash from secret, recipient, and nonce.
|
|
142
|
+
* Useful for verifying parameters before delivery.
|
|
143
|
+
*/
|
|
144
|
+
static computeHash(secret: string, recipient: string, nonce: string): string;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
export { BEARERSWAP_V3_ABI, BEARERSWAP_V3_ADDRESS, BearerSwap, type BearerSwapConfig, type CommitResult, type DeliverResult, type RelayerStatus, type ResolveResult, BearerSwap as default };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
BEARERSWAP_V3_ABI: () => BEARERSWAP_V3_ABI,
|
|
24
|
+
BEARERSWAP_V3_ADDRESS: () => BEARERSWAP_V3_ADDRESS,
|
|
25
|
+
BearerSwap: () => BearerSwap,
|
|
26
|
+
default: () => index_default
|
|
27
|
+
});
|
|
28
|
+
module.exports = __toCommonJS(index_exports);
|
|
29
|
+
var import_ethers = require("ethers");
|
|
30
|
+
var BEARERSWAP_V3_ADDRESS = "0x5de315Dab49012c5bbeC41d7a3B25c6829a3e566";
|
|
31
|
+
var BEARERSWAP_V3_ABI = [
|
|
32
|
+
"function commit(bytes32 hash, address token, uint256 amount) external payable",
|
|
33
|
+
"function reveal(bytes32 secret, address recipient, bytes32 nonce) external",
|
|
34
|
+
"function commitments(bytes32 hash) view returns (address sender, address token, uint256 amount, uint256 timestamp, bool settled)",
|
|
35
|
+
"function paused() view returns (bool)",
|
|
36
|
+
"function pendingCount() view returns (uint256)",
|
|
37
|
+
"function getRecommendedETH() view returns (uint256)",
|
|
38
|
+
"function getMinETH() pure returns (uint256)",
|
|
39
|
+
"function verifyPreimage(bytes32 secret, address recipient, bytes32 nonce) view returns (bytes32)"
|
|
40
|
+
];
|
|
41
|
+
var ERC20_ABI = [
|
|
42
|
+
"function approve(address spender, uint256 amount) external returns (bool)",
|
|
43
|
+
"function allowance(address owner, address spender) view returns (uint256)",
|
|
44
|
+
"function balanceOf(address account) view returns (uint256)",
|
|
45
|
+
"function decimals() view returns (uint8)"
|
|
46
|
+
];
|
|
47
|
+
var BearerSwap = class {
|
|
48
|
+
constructor(config = {}) {
|
|
49
|
+
this.provider = null;
|
|
50
|
+
this.signer = null;
|
|
51
|
+
this.relayerUrl = (config.relayerUrl || "https://flat.cash").replace(
|
|
52
|
+
/\/$/,
|
|
53
|
+
""
|
|
54
|
+
);
|
|
55
|
+
if (config.signer) {
|
|
56
|
+
this.signer = config.signer;
|
|
57
|
+
this.provider = config.signer.provider || null;
|
|
58
|
+
} else if (config.privateKey) {
|
|
59
|
+
const provider = config.provider || new import_ethers.ethers.JsonRpcProvider(config.rpcUrl || "https://eth.drpc.org");
|
|
60
|
+
this.provider = provider;
|
|
61
|
+
this.signer = new import_ethers.ethers.Wallet(config.privateKey, provider);
|
|
62
|
+
} else if (config.provider) {
|
|
63
|
+
this.provider = config.provider;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
/** Contract address */
|
|
67
|
+
get contractAddress() {
|
|
68
|
+
return BEARERSWAP_V3_ADDRESS;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Commit tokens on-chain for private transfer.
|
|
72
|
+
*
|
|
73
|
+
* This locks tokens in the BearerSwap contract. The returned secret and
|
|
74
|
+
* nonce must be shared with the recipient off-chain (e.g., via encrypted
|
|
75
|
+
* message, QR code, or any private channel).
|
|
76
|
+
*
|
|
77
|
+
* @param token - ERC-20 token address
|
|
78
|
+
* @param amount - Amount to send (human-readable, e.g., "100.0")
|
|
79
|
+
* @param recipient - Recipient Ethereum address
|
|
80
|
+
* @param decimals - Token decimals (default: 18)
|
|
81
|
+
*/
|
|
82
|
+
async commit(token, amount, recipient, decimals = 18) {
|
|
83
|
+
if (!this.signer) {
|
|
84
|
+
throw new Error(
|
|
85
|
+
"Signer required for commit. Provide privateKey or signer in config."
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
const secret = import_ethers.ethers.hexlify(import_ethers.ethers.randomBytes(32));
|
|
89
|
+
const nonce = import_ethers.ethers.hexlify(import_ethers.ethers.randomBytes(32));
|
|
90
|
+
const commitHash = import_ethers.ethers.solidityPackedKeccak256(
|
|
91
|
+
["bytes32", "address", "bytes32"],
|
|
92
|
+
[secret, recipient, nonce]
|
|
93
|
+
);
|
|
94
|
+
const amountWei = import_ethers.ethers.parseUnits(amount, decimals);
|
|
95
|
+
const tokenContract = new import_ethers.ethers.Contract(token, ERC20_ABI, this.signer);
|
|
96
|
+
const signerAddress = await this.signer.getAddress();
|
|
97
|
+
const currentAllowance = await tokenContract.allowance(
|
|
98
|
+
signerAddress,
|
|
99
|
+
BEARERSWAP_V3_ADDRESS
|
|
100
|
+
);
|
|
101
|
+
if (currentAllowance < amountWei) {
|
|
102
|
+
const approveTx = await tokenContract.approve(
|
|
103
|
+
BEARERSWAP_V3_ADDRESS,
|
|
104
|
+
amountWei
|
|
105
|
+
);
|
|
106
|
+
await approveTx.wait();
|
|
107
|
+
}
|
|
108
|
+
const contract = new import_ethers.ethers.Contract(
|
|
109
|
+
BEARERSWAP_V3_ADDRESS,
|
|
110
|
+
BEARERSWAP_V3_ABI,
|
|
111
|
+
this.signer
|
|
112
|
+
);
|
|
113
|
+
const recommendedETH = await contract.getRecommendedETH();
|
|
114
|
+
const tx = await contract.commit(commitHash, token, amountWei, {
|
|
115
|
+
value: recommendedETH,
|
|
116
|
+
gasLimit: 15e4
|
|
117
|
+
});
|
|
118
|
+
const receipt = await tx.wait();
|
|
119
|
+
return {
|
|
120
|
+
secret,
|
|
121
|
+
nonce,
|
|
122
|
+
commitHash,
|
|
123
|
+
txHash: receipt.hash,
|
|
124
|
+
amount,
|
|
125
|
+
token,
|
|
126
|
+
recipient
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Deliver a committed transfer to the recipient via the relayer.
|
|
131
|
+
*
|
|
132
|
+
* The relayer adds a random privacy delay (2–45 min) before executing
|
|
133
|
+
* the on-chain reveal, breaking timing correlation between commit and reveal.
|
|
134
|
+
*
|
|
135
|
+
* @param secret - The secret from the commit step
|
|
136
|
+
* @param recipient - The recipient address
|
|
137
|
+
* @param nonce - The nonce from the commit step
|
|
138
|
+
*/
|
|
139
|
+
async deliver(secret, recipient, nonce) {
|
|
140
|
+
const response = await fetch(`${this.relayerUrl}/api/bearer/deliver`, {
|
|
141
|
+
method: "POST",
|
|
142
|
+
headers: { "Content-Type": "application/json" },
|
|
143
|
+
body: JSON.stringify({ secret, recipient, nonce })
|
|
144
|
+
});
|
|
145
|
+
if (!response.ok) {
|
|
146
|
+
const error = await response.json().catch(() => ({ error: "Unknown error" }));
|
|
147
|
+
throw new Error(
|
|
148
|
+
`Delivery failed (${response.status}): ${error.error || error.details || "Unknown error"}`
|
|
149
|
+
);
|
|
150
|
+
}
|
|
151
|
+
return response.json();
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Check relayer status (balance, queue size, availability).
|
|
155
|
+
*/
|
|
156
|
+
async status() {
|
|
157
|
+
const response = await fetch(`${this.relayerUrl}/api/bearer/status`);
|
|
158
|
+
if (!response.ok) {
|
|
159
|
+
throw new Error(`Status check failed (${response.status})`);
|
|
160
|
+
}
|
|
161
|
+
return response.json();
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Resolve a FlatID username or ENS name to an Ethereum address.
|
|
165
|
+
*
|
|
166
|
+
* @param identifier - FlatID username, ENS name, or Ethereum address
|
|
167
|
+
*/
|
|
168
|
+
async resolve(identifier) {
|
|
169
|
+
const response = await fetch(
|
|
170
|
+
`${this.relayerUrl}/api/bearer/resolve/${encodeURIComponent(identifier)}`
|
|
171
|
+
);
|
|
172
|
+
if (!response.ok) {
|
|
173
|
+
const error = await response.json().catch(() => ({ error: "Not found" }));
|
|
174
|
+
throw new Error(
|
|
175
|
+
`Resolve failed (${response.status}): ${error.error || "Not found"}`
|
|
176
|
+
);
|
|
177
|
+
}
|
|
178
|
+
return response.json();
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Check the status of a specific commitment on-chain.
|
|
182
|
+
*
|
|
183
|
+
* @param commitHash - The commit hash (bytes32)
|
|
184
|
+
*/
|
|
185
|
+
async getCommitment(commitHash) {
|
|
186
|
+
const provider = this.provider || new import_ethers.ethers.JsonRpcProvider("https://eth.drpc.org");
|
|
187
|
+
const contract = new import_ethers.ethers.Contract(
|
|
188
|
+
BEARERSWAP_V3_ADDRESS,
|
|
189
|
+
BEARERSWAP_V3_ABI,
|
|
190
|
+
provider
|
|
191
|
+
);
|
|
192
|
+
const result = await contract.commitments(commitHash);
|
|
193
|
+
return {
|
|
194
|
+
sender: result.sender,
|
|
195
|
+
token: result.token,
|
|
196
|
+
amount: result.amount,
|
|
197
|
+
timestamp: result.timestamp,
|
|
198
|
+
settled: result.settled
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Compute the commit hash from secret, recipient, and nonce.
|
|
203
|
+
* Useful for verifying parameters before delivery.
|
|
204
|
+
*/
|
|
205
|
+
static computeHash(secret, recipient, nonce) {
|
|
206
|
+
return import_ethers.ethers.solidityPackedKeccak256(
|
|
207
|
+
["bytes32", "address", "bytes32"],
|
|
208
|
+
[secret, recipient, nonce]
|
|
209
|
+
);
|
|
210
|
+
}
|
|
211
|
+
};
|
|
212
|
+
var index_default = BearerSwap;
|
|
213
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
214
|
+
0 && (module.exports = {
|
|
215
|
+
BEARERSWAP_V3_ABI,
|
|
216
|
+
BEARERSWAP_V3_ADDRESS,
|
|
217
|
+
BearerSwap
|
|
218
|
+
});
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
import { ethers } from "ethers";
|
|
3
|
+
var BEARERSWAP_V3_ADDRESS = "0x5de315Dab49012c5bbeC41d7a3B25c6829a3e566";
|
|
4
|
+
var BEARERSWAP_V3_ABI = [
|
|
5
|
+
"function commit(bytes32 hash, address token, uint256 amount) external payable",
|
|
6
|
+
"function reveal(bytes32 secret, address recipient, bytes32 nonce) external",
|
|
7
|
+
"function commitments(bytes32 hash) view returns (address sender, address token, uint256 amount, uint256 timestamp, bool settled)",
|
|
8
|
+
"function paused() view returns (bool)",
|
|
9
|
+
"function pendingCount() view returns (uint256)",
|
|
10
|
+
"function getRecommendedETH() view returns (uint256)",
|
|
11
|
+
"function getMinETH() pure returns (uint256)",
|
|
12
|
+
"function verifyPreimage(bytes32 secret, address recipient, bytes32 nonce) view returns (bytes32)"
|
|
13
|
+
];
|
|
14
|
+
var ERC20_ABI = [
|
|
15
|
+
"function approve(address spender, uint256 amount) external returns (bool)",
|
|
16
|
+
"function allowance(address owner, address spender) view returns (uint256)",
|
|
17
|
+
"function balanceOf(address account) view returns (uint256)",
|
|
18
|
+
"function decimals() view returns (uint8)"
|
|
19
|
+
];
|
|
20
|
+
var BearerSwap = class {
|
|
21
|
+
constructor(config = {}) {
|
|
22
|
+
this.provider = null;
|
|
23
|
+
this.signer = null;
|
|
24
|
+
this.relayerUrl = (config.relayerUrl || "https://flat.cash").replace(
|
|
25
|
+
/\/$/,
|
|
26
|
+
""
|
|
27
|
+
);
|
|
28
|
+
if (config.signer) {
|
|
29
|
+
this.signer = config.signer;
|
|
30
|
+
this.provider = config.signer.provider || null;
|
|
31
|
+
} else if (config.privateKey) {
|
|
32
|
+
const provider = config.provider || new ethers.JsonRpcProvider(config.rpcUrl || "https://eth.drpc.org");
|
|
33
|
+
this.provider = provider;
|
|
34
|
+
this.signer = new ethers.Wallet(config.privateKey, provider);
|
|
35
|
+
} else if (config.provider) {
|
|
36
|
+
this.provider = config.provider;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
/** Contract address */
|
|
40
|
+
get contractAddress() {
|
|
41
|
+
return BEARERSWAP_V3_ADDRESS;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Commit tokens on-chain for private transfer.
|
|
45
|
+
*
|
|
46
|
+
* This locks tokens in the BearerSwap contract. The returned secret and
|
|
47
|
+
* nonce must be shared with the recipient off-chain (e.g., via encrypted
|
|
48
|
+
* message, QR code, or any private channel).
|
|
49
|
+
*
|
|
50
|
+
* @param token - ERC-20 token address
|
|
51
|
+
* @param amount - Amount to send (human-readable, e.g., "100.0")
|
|
52
|
+
* @param recipient - Recipient Ethereum address
|
|
53
|
+
* @param decimals - Token decimals (default: 18)
|
|
54
|
+
*/
|
|
55
|
+
async commit(token, amount, recipient, decimals = 18) {
|
|
56
|
+
if (!this.signer) {
|
|
57
|
+
throw new Error(
|
|
58
|
+
"Signer required for commit. Provide privateKey or signer in config."
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
const secret = ethers.hexlify(ethers.randomBytes(32));
|
|
62
|
+
const nonce = ethers.hexlify(ethers.randomBytes(32));
|
|
63
|
+
const commitHash = ethers.solidityPackedKeccak256(
|
|
64
|
+
["bytes32", "address", "bytes32"],
|
|
65
|
+
[secret, recipient, nonce]
|
|
66
|
+
);
|
|
67
|
+
const amountWei = ethers.parseUnits(amount, decimals);
|
|
68
|
+
const tokenContract = new ethers.Contract(token, ERC20_ABI, this.signer);
|
|
69
|
+
const signerAddress = await this.signer.getAddress();
|
|
70
|
+
const currentAllowance = await tokenContract.allowance(
|
|
71
|
+
signerAddress,
|
|
72
|
+
BEARERSWAP_V3_ADDRESS
|
|
73
|
+
);
|
|
74
|
+
if (currentAllowance < amountWei) {
|
|
75
|
+
const approveTx = await tokenContract.approve(
|
|
76
|
+
BEARERSWAP_V3_ADDRESS,
|
|
77
|
+
amountWei
|
|
78
|
+
);
|
|
79
|
+
await approveTx.wait();
|
|
80
|
+
}
|
|
81
|
+
const contract = new ethers.Contract(
|
|
82
|
+
BEARERSWAP_V3_ADDRESS,
|
|
83
|
+
BEARERSWAP_V3_ABI,
|
|
84
|
+
this.signer
|
|
85
|
+
);
|
|
86
|
+
const recommendedETH = await contract.getRecommendedETH();
|
|
87
|
+
const tx = await contract.commit(commitHash, token, amountWei, {
|
|
88
|
+
value: recommendedETH,
|
|
89
|
+
gasLimit: 15e4
|
|
90
|
+
});
|
|
91
|
+
const receipt = await tx.wait();
|
|
92
|
+
return {
|
|
93
|
+
secret,
|
|
94
|
+
nonce,
|
|
95
|
+
commitHash,
|
|
96
|
+
txHash: receipt.hash,
|
|
97
|
+
amount,
|
|
98
|
+
token,
|
|
99
|
+
recipient
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Deliver a committed transfer to the recipient via the relayer.
|
|
104
|
+
*
|
|
105
|
+
* The relayer adds a random privacy delay (2–45 min) before executing
|
|
106
|
+
* the on-chain reveal, breaking timing correlation between commit and reveal.
|
|
107
|
+
*
|
|
108
|
+
* @param secret - The secret from the commit step
|
|
109
|
+
* @param recipient - The recipient address
|
|
110
|
+
* @param nonce - The nonce from the commit step
|
|
111
|
+
*/
|
|
112
|
+
async deliver(secret, recipient, nonce) {
|
|
113
|
+
const response = await fetch(`${this.relayerUrl}/api/bearer/deliver`, {
|
|
114
|
+
method: "POST",
|
|
115
|
+
headers: { "Content-Type": "application/json" },
|
|
116
|
+
body: JSON.stringify({ secret, recipient, nonce })
|
|
117
|
+
});
|
|
118
|
+
if (!response.ok) {
|
|
119
|
+
const error = await response.json().catch(() => ({ error: "Unknown error" }));
|
|
120
|
+
throw new Error(
|
|
121
|
+
`Delivery failed (${response.status}): ${error.error || error.details || "Unknown error"}`
|
|
122
|
+
);
|
|
123
|
+
}
|
|
124
|
+
return response.json();
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Check relayer status (balance, queue size, availability).
|
|
128
|
+
*/
|
|
129
|
+
async status() {
|
|
130
|
+
const response = await fetch(`${this.relayerUrl}/api/bearer/status`);
|
|
131
|
+
if (!response.ok) {
|
|
132
|
+
throw new Error(`Status check failed (${response.status})`);
|
|
133
|
+
}
|
|
134
|
+
return response.json();
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Resolve a FlatID username or ENS name to an Ethereum address.
|
|
138
|
+
*
|
|
139
|
+
* @param identifier - FlatID username, ENS name, or Ethereum address
|
|
140
|
+
*/
|
|
141
|
+
async resolve(identifier) {
|
|
142
|
+
const response = await fetch(
|
|
143
|
+
`${this.relayerUrl}/api/bearer/resolve/${encodeURIComponent(identifier)}`
|
|
144
|
+
);
|
|
145
|
+
if (!response.ok) {
|
|
146
|
+
const error = await response.json().catch(() => ({ error: "Not found" }));
|
|
147
|
+
throw new Error(
|
|
148
|
+
`Resolve failed (${response.status}): ${error.error || "Not found"}`
|
|
149
|
+
);
|
|
150
|
+
}
|
|
151
|
+
return response.json();
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Check the status of a specific commitment on-chain.
|
|
155
|
+
*
|
|
156
|
+
* @param commitHash - The commit hash (bytes32)
|
|
157
|
+
*/
|
|
158
|
+
async getCommitment(commitHash) {
|
|
159
|
+
const provider = this.provider || new ethers.JsonRpcProvider("https://eth.drpc.org");
|
|
160
|
+
const contract = new ethers.Contract(
|
|
161
|
+
BEARERSWAP_V3_ADDRESS,
|
|
162
|
+
BEARERSWAP_V3_ABI,
|
|
163
|
+
provider
|
|
164
|
+
);
|
|
165
|
+
const result = await contract.commitments(commitHash);
|
|
166
|
+
return {
|
|
167
|
+
sender: result.sender,
|
|
168
|
+
token: result.token,
|
|
169
|
+
amount: result.amount,
|
|
170
|
+
timestamp: result.timestamp,
|
|
171
|
+
settled: result.settled
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Compute the commit hash from secret, recipient, and nonce.
|
|
176
|
+
* Useful for verifying parameters before delivery.
|
|
177
|
+
*/
|
|
178
|
+
static computeHash(secret, recipient, nonce) {
|
|
179
|
+
return ethers.solidityPackedKeccak256(
|
|
180
|
+
["bytes32", "address", "bytes32"],
|
|
181
|
+
[secret, recipient, nonce]
|
|
182
|
+
);
|
|
183
|
+
}
|
|
184
|
+
};
|
|
185
|
+
var index_default = BearerSwap;
|
|
186
|
+
export {
|
|
187
|
+
BEARERSWAP_V3_ABI,
|
|
188
|
+
BEARERSWAP_V3_ADDRESS,
|
|
189
|
+
BearerSwap,
|
|
190
|
+
index_default as default
|
|
191
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@flatcash/bearerswap",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "BearerSwap SDK — Private token transfers on Ethereum. Send any ERC-20 token privately with zero-knowledge commit-reveal.",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"module": "dist/index.mjs",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": "./dist/index.mjs",
|
|
11
|
+
"require": "./dist/index.js",
|
|
12
|
+
"types": "./dist/index.d.ts"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"files": ["dist", "README.md"],
|
|
16
|
+
"keywords": ["ethereum", "privacy", "erc20", "token-transfer", "bearerswap", "flat", "save", "commit-reveal", "private-transfer"],
|
|
17
|
+
"license": "MIT",
|
|
18
|
+
"repository": {
|
|
19
|
+
"type": "git",
|
|
20
|
+
"url": "https://github.com/AuditTester1/bearerswap-sdk"
|
|
21
|
+
},
|
|
22
|
+
"homepage": "https://flat.cash/developers",
|
|
23
|
+
"peerDependencies": {
|
|
24
|
+
"ethers": "^6.0.0"
|
|
25
|
+
},
|
|
26
|
+
"devDependencies": {
|
|
27
|
+
"ethers": "^6.13.0",
|
|
28
|
+
"tsup": "^8.0.0",
|
|
29
|
+
"typescript": "^5.5.0"
|
|
30
|
+
},
|
|
31
|
+
"scripts": {
|
|
32
|
+
"build": "tsup src/index.ts --format cjs,esm --dts",
|
|
33
|
+
"prepublishOnly": "npm run build"
|
|
34
|
+
}
|
|
35
|
+
}
|