cipherpay-sdk 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/README.md +91 -0
- package/dist/CipherPay.d.ts +61 -0
- package/dist/CipherPay.d.ts.map +1 -0
- package/dist/CipherPay.js +217 -0
- package/dist/CipherPay.js.map +1 -0
- package/dist/hooks/useCheckout.d.ts +26 -0
- package/dist/hooks/useCheckout.d.ts.map +1 -0
- package/dist/hooks/useCheckout.js +134 -0
- package/dist/hooks/useCheckout.js.map +1 -0
- package/dist/hooks/useShieldedBalance.d.ts +19 -0
- package/dist/hooks/useShieldedBalance.d.ts.map +1 -0
- package/dist/hooks/useShieldedBalance.js +59 -0
- package/dist/hooks/useShieldedBalance.js.map +1 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +26 -0
- package/dist/index.js.map +1 -0
- package/dist/react.d.ts +12 -0
- package/dist/react.d.ts.map +1 -0
- package/dist/react.js +11 -0
- package/dist/react.js.map +1 -0
- package/dist/types.d.ts +57 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/webhooks.d.ts +36 -0
- package/dist/webhooks.d.ts.map +1 -0
- package/dist/webhooks.js +101 -0
- package/dist/webhooks.js.map +1 -0
- package/package.json +54 -0
package/README.md
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# cipherpay-sdk
|
|
2
|
+
|
|
3
|
+
Confidential payroll & payments SDK for [CipherPay](https://cipherpayy.vercel.app) on
|
|
4
|
+
Fhenix FHE. Run encrypted payroll, charge invoices, relay webhooks, and drop a pay button
|
|
5
|
+
into a React app — every amount stays encrypted as an FHE ciphertext on-chain.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install cipherpay-sdk
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Peer dependencies: `@cofhe/sdk` and `viem` are required; `react` and `wagmi` are only
|
|
14
|
+
needed for the React hooks (`cipherpay-sdk/react`).
|
|
15
|
+
|
|
16
|
+
## Run a confidential payroll (Node / server)
|
|
17
|
+
|
|
18
|
+
```ts
|
|
19
|
+
import { CipherPay } from 'cipherpay-sdk';
|
|
20
|
+
|
|
21
|
+
const cp = new CipherPay({
|
|
22
|
+
rpcUrl: process.env.SEPOLIA_RPC_URL!,
|
|
23
|
+
privateKey: process.env.PAYER_PRIVATE_KEY!, // employer / DAO treasury key
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
const result = await cp.runPayroll({
|
|
27
|
+
memo: 'April Payroll',
|
|
28
|
+
recipients: [
|
|
29
|
+
{ address: '0xAbc...', amount: '2500.00' },
|
|
30
|
+
{ address: '0xDef...', amount: '1800.00' },
|
|
31
|
+
],
|
|
32
|
+
onProgress: (step) => console.log(step), // initTfhe → encrypting → submitting → confirming
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
console.log('Payroll batch tx:', result.txHash);
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Each salary is FHE-encrypted before it reaches the chain. The batch is created in one
|
|
39
|
+
`BatchCipher` transaction; each recipient can later claim and decrypt **only their own
|
|
40
|
+
row** — no recipient, and no on-chain observer, sees another person's amount.
|
|
41
|
+
|
|
42
|
+
## Charge a single invoice
|
|
43
|
+
|
|
44
|
+
```ts
|
|
45
|
+
await cp.charge({ invoiceId: '0x...', amount: '0.01' });
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Webhooks
|
|
49
|
+
|
|
50
|
+
```ts
|
|
51
|
+
import { CipherPay, CipherPayWebhooks } from 'cipherpay-sdk';
|
|
52
|
+
|
|
53
|
+
new CipherPayWebhooks({
|
|
54
|
+
rpcUrl: process.env.SEPOLIA_RPC_URL!,
|
|
55
|
+
endpoint: 'https://my-app.com/webhooks/cipherpay',
|
|
56
|
+
secret: process.env.CIPHERPAY_WEBHOOK_SECRET!,
|
|
57
|
+
}).start();
|
|
58
|
+
|
|
59
|
+
// In your webhook handler — verify the signature before trusting the payload:
|
|
60
|
+
const ok = CipherPay.verifyWebhook(rawBody, req.headers['x-cipherpay-signature'], secret);
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
`verifyWebhook` recomputes `HMAC-SHA256(secret, rawBody)` and compares it in constant time.
|
|
64
|
+
|
|
65
|
+
## React hook
|
|
66
|
+
|
|
67
|
+
```tsx
|
|
68
|
+
import { useCheckout } from 'cipherpay-sdk/react';
|
|
69
|
+
|
|
70
|
+
function PayButton({ invoiceHash }: { invoiceHash: string }) {
|
|
71
|
+
const { pay, status, txHash } = useCheckout(invoiceHash);
|
|
72
|
+
return (
|
|
73
|
+
<button onClick={() => pay({ amount: '0.01' })} disabled={status !== 'idle'}>
|
|
74
|
+
{status === 'encrypting' ? 'Encrypting…' : 'Pay with CipherPay'}
|
|
75
|
+
</button>
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
The hook must render inside a wagmi `<WagmiProvider>`.
|
|
81
|
+
|
|
82
|
+
## Build from source
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
npm install
|
|
86
|
+
npm run build # tsc → dist/
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## License
|
|
90
|
+
|
|
91
|
+
MIT
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import type { ChargeOptions, ChargeResult, PayrollOptions, PayrollResult, CipherPayConfig } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* CipherPay — server-side / Node.js SDK for CipherPay protocol.
|
|
4
|
+
*
|
|
5
|
+
* Stripe-like API:
|
|
6
|
+
* const cp = new CipherPay({ rpcUrl, privateKey });
|
|
7
|
+
* const result = await cp.charge({ invoiceId: '0x...', amount: '0.01' });
|
|
8
|
+
*
|
|
9
|
+
* The SDK handles:
|
|
10
|
+
* 1. FHE encryption of payment amount via @cofhe/sdk Node.js client
|
|
11
|
+
* 2. Contract interaction (payInvoice / payInvoiceShielded / claimAnonymously)
|
|
12
|
+
* 3. Transaction confirmation and result enrichment
|
|
13
|
+
*/
|
|
14
|
+
export declare class CipherPay {
|
|
15
|
+
private config;
|
|
16
|
+
constructor(config: CipherPayConfig);
|
|
17
|
+
/**
|
|
18
|
+
* Charge an invoice — FHE-encrypt the amount and submit payment.
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* const result = await cp.charge({
|
|
22
|
+
* invoiceId: '0xabc...',
|
|
23
|
+
* amount: '0.01',
|
|
24
|
+
* onProgress: (step) => console.log(step),
|
|
25
|
+
* });
|
|
26
|
+
* console.log('Paid:', result.txHash);
|
|
27
|
+
*/
|
|
28
|
+
charge(opts: ChargeOptions): Promise<ChargeResult>;
|
|
29
|
+
/**
|
|
30
|
+
* Run a confidential payroll batch.
|
|
31
|
+
*
|
|
32
|
+
* Every salary is FHE-encrypted, then a single `BatchCipher` transaction
|
|
33
|
+
* creates one encrypted row per recipient. Each recipient can later claim and
|
|
34
|
+
* decrypt only their own row — no recipient, and no on-chain observer, sees
|
|
35
|
+
* another person's amount.
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* await cp.runPayroll({
|
|
39
|
+
* recipients: [
|
|
40
|
+
* { address: '0xabc...', amount: '2500.00' },
|
|
41
|
+
* { address: '0xdef...', amount: '1800.00' },
|
|
42
|
+
* ],
|
|
43
|
+
* memo: 'April Payroll',
|
|
44
|
+
* });
|
|
45
|
+
*/
|
|
46
|
+
runPayroll(opts: PayrollOptions): Promise<PayrollResult>;
|
|
47
|
+
/**
|
|
48
|
+
* Verify a webhook event signature.
|
|
49
|
+
*
|
|
50
|
+
* `CipherPayWebhooks` signs every delivery as `HMAC-SHA256(secret, rawBody)`
|
|
51
|
+
* and sends the hex digest in the `X-CipherPay-Signature` header. This
|
|
52
|
+
* recomputes the digest and compares it to the received one in constant
|
|
53
|
+
* time, so a merchant can reject forged or tampered webhook calls.
|
|
54
|
+
*
|
|
55
|
+
* @param payload the exact raw request body that was signed
|
|
56
|
+
* @param signature the hex digest from the `X-CipherPay-Signature` header
|
|
57
|
+
* @param secret the shared webhook secret (`whsec_...`)
|
|
58
|
+
*/
|
|
59
|
+
static verifyWebhook(payload: string, signature: string, secret: string): boolean;
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=CipherPay.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CipherPay.d.ts","sourceRoot":"","sources":["../src/CipherPay.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,aAAa,EAAE,YAAY,EAC3B,cAAc,EAAE,aAAa,EAC7B,eAAe,EAChB,MAAM,SAAS,CAAC;AAQjB;;;;;;;;;;;GAWG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,MAAM,CAA4B;gBAE9B,MAAM,EAAE,eAAe;IASnC;;;;;;;;;;OAUG;IACG,MAAM,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC;IA8ExD;;;;;;;;;;;;;;;;OAgBG;IACG,UAAU,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC;IAgF9D;;;;;;;;;;;OAWG;IACH,MAAM,CAAC,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO;CAgBlF"}
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
import { createHmac, timingSafeEqual } from 'node:crypto';
|
|
2
|
+
// CipherPayFHE contract address on Ethereum Sepolia
|
|
3
|
+
const DEFAULT_CONTRACT = '0x305eF265BD964fBe34913E70Ef6AA8951e6b662e';
|
|
4
|
+
const DEFAULT_CHAIN_ID = 11155111;
|
|
5
|
+
// BatchCipher — confidential batch payroll — on Ethereum Sepolia
|
|
6
|
+
const BATCH_CIPHER_ADDRESS = '0x347fb466f3c9bC031560b49973ec05BdAdD2d4C4';
|
|
7
|
+
/**
|
|
8
|
+
* CipherPay — server-side / Node.js SDK for CipherPay protocol.
|
|
9
|
+
*
|
|
10
|
+
* Stripe-like API:
|
|
11
|
+
* const cp = new CipherPay({ rpcUrl, privateKey });
|
|
12
|
+
* const result = await cp.charge({ invoiceId: '0x...', amount: '0.01' });
|
|
13
|
+
*
|
|
14
|
+
* The SDK handles:
|
|
15
|
+
* 1. FHE encryption of payment amount via @cofhe/sdk Node.js client
|
|
16
|
+
* 2. Contract interaction (payInvoice / payInvoiceShielded / claimAnonymously)
|
|
17
|
+
* 3. Transaction confirmation and result enrichment
|
|
18
|
+
*/
|
|
19
|
+
export class CipherPay {
|
|
20
|
+
config;
|
|
21
|
+
constructor(config) {
|
|
22
|
+
this.config = {
|
|
23
|
+
rpcUrl: config.rpcUrl,
|
|
24
|
+
privateKey: config.privateKey || '',
|
|
25
|
+
chainId: config.chainId ?? DEFAULT_CHAIN_ID,
|
|
26
|
+
contract: config.contract ?? DEFAULT_CONTRACT,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Charge an invoice — FHE-encrypt the amount and submit payment.
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* const result = await cp.charge({
|
|
34
|
+
* invoiceId: '0xabc...',
|
|
35
|
+
* amount: '0.01',
|
|
36
|
+
* onProgress: (step) => console.log(step),
|
|
37
|
+
* });
|
|
38
|
+
* console.log('Paid:', result.txHash);
|
|
39
|
+
*/
|
|
40
|
+
async charge(opts) {
|
|
41
|
+
const { invoiceId, amount, shielded = false, anonymous = false, onProgress } = opts;
|
|
42
|
+
onProgress?.('initTfhe');
|
|
43
|
+
// Dynamic import for tree-shaking — cofhe/sdk only loaded when charge() is called
|
|
44
|
+
const { createCofheConfig, createCofheClient } = await import('@cofhe/sdk/node');
|
|
45
|
+
const { Encryptable } = await import('@cofhe/sdk');
|
|
46
|
+
const { createPublicClient, createWalletClient, http, parseEther } = await import('viem');
|
|
47
|
+
const { privateKeyToAccount } = await import('viem/accounts');
|
|
48
|
+
const { sepolia } = await import('viem/chains');
|
|
49
|
+
const account = privateKeyToAccount(this.config.privateKey);
|
|
50
|
+
const publicClient = createPublicClient({ chain: sepolia, transport: http(this.config.rpcUrl) });
|
|
51
|
+
const walletClient = createWalletClient({ account, chain: sepolia, transport: http(this.config.rpcUrl) });
|
|
52
|
+
const cofheConfig = createCofheConfig({ supportedChains: [sepolia] });
|
|
53
|
+
const cofheClient = createCofheClient(cofheConfig);
|
|
54
|
+
await cofheClient.connect(publicClient, walletClient);
|
|
55
|
+
onProgress?.('encrypting');
|
|
56
|
+
const amountWei = parseEther(amount);
|
|
57
|
+
const [encAmount] = await cofheClient.encryptInputs([Encryptable.uint64(amountWei)]).execute();
|
|
58
|
+
const encTuple = {
|
|
59
|
+
ctHash: BigInt(encAmount.ctHash ?? 0),
|
|
60
|
+
securityZone: encAmount.securityZone ?? 0,
|
|
61
|
+
utype: encAmount.utype ?? 5,
|
|
62
|
+
signature: encAmount.signature ?? '0x',
|
|
63
|
+
};
|
|
64
|
+
onProgress?.('submitting');
|
|
65
|
+
// Import minimal ABI inline — avoids needing the full contract.ts in sdk
|
|
66
|
+
const payAbi = [{
|
|
67
|
+
name: anonymous ? 'claimAnonymously' : shielded ? 'payInvoiceShielded' : 'payInvoice',
|
|
68
|
+
type: 'function',
|
|
69
|
+
stateMutability: anonymous || shielded ? 'nonpayable' : 'payable',
|
|
70
|
+
inputs: anonymous
|
|
71
|
+
? [{ name: '_invoiceHash', type: 'bytes32' }, { name: '_encryptedPayment', type: 'tuple', components: [{ name: 'ctHash', type: 'uint256' }, { name: 'securityZone', type: 'uint8' }, { name: 'utype', type: 'uint8' }, { name: 'signature', type: 'bytes' }] }, { name: '_nullifier', type: 'bytes32' }]
|
|
72
|
+
: [{ name: '_invoiceHash', type: 'bytes32' }, { name: '_encryptedPayment', type: 'tuple', components: [{ name: 'ctHash', type: 'uint256' }, { name: 'securityZone', type: 'uint8' }, { name: 'utype', type: 'uint8' }, { name: 'signature', type: 'bytes' }] }],
|
|
73
|
+
outputs: [],
|
|
74
|
+
}];
|
|
75
|
+
const { keccak256, encodePacked } = await import('viem');
|
|
76
|
+
const nullifier = opts.nullifier
|
|
77
|
+
? opts.nullifier
|
|
78
|
+
: keccak256(encodePacked(['address', 'bytes32'], [account.address, invoiceId]));
|
|
79
|
+
const args = anonymous
|
|
80
|
+
? [invoiceId, encTuple, nullifier]
|
|
81
|
+
: [invoiceId, encTuple];
|
|
82
|
+
if (shielded) {
|
|
83
|
+
args.push(amountWei); // _maxDebit
|
|
84
|
+
}
|
|
85
|
+
const txHash = await walletClient.writeContract({
|
|
86
|
+
address: this.config.contract,
|
|
87
|
+
abi: payAbi,
|
|
88
|
+
functionName: payAbi[0].name,
|
|
89
|
+
args,
|
|
90
|
+
value: anonymous || shielded ? 0n : amountWei,
|
|
91
|
+
});
|
|
92
|
+
onProgress?.('confirming');
|
|
93
|
+
const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash });
|
|
94
|
+
return {
|
|
95
|
+
txHash,
|
|
96
|
+
invoiceId,
|
|
97
|
+
amount,
|
|
98
|
+
shielded,
|
|
99
|
+
anonymous,
|
|
100
|
+
blockNumber: receipt.blockNumber,
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Run a confidential payroll batch.
|
|
105
|
+
*
|
|
106
|
+
* Every salary is FHE-encrypted, then a single `BatchCipher` transaction
|
|
107
|
+
* creates one encrypted row per recipient. Each recipient can later claim and
|
|
108
|
+
* decrypt only their own row — no recipient, and no on-chain observer, sees
|
|
109
|
+
* another person's amount.
|
|
110
|
+
*
|
|
111
|
+
* @example
|
|
112
|
+
* await cp.runPayroll({
|
|
113
|
+
* recipients: [
|
|
114
|
+
* { address: '0xabc...', amount: '2500.00' },
|
|
115
|
+
* { address: '0xdef...', amount: '1800.00' },
|
|
116
|
+
* ],
|
|
117
|
+
* memo: 'April Payroll',
|
|
118
|
+
* });
|
|
119
|
+
*/
|
|
120
|
+
async runPayroll(opts) {
|
|
121
|
+
const { recipients, memo = 'Payroll', onProgress } = opts;
|
|
122
|
+
if (recipients.length === 0 || recipients.length > 100) {
|
|
123
|
+
throw new Error('runPayroll: 1–100 recipients required per batch');
|
|
124
|
+
}
|
|
125
|
+
onProgress?.('initTfhe');
|
|
126
|
+
const { createCofheConfig, createCofheClient } = await import('@cofhe/sdk/node');
|
|
127
|
+
const { Encryptable } = await import('@cofhe/sdk');
|
|
128
|
+
const { createPublicClient, createWalletClient, http, parseEther, keccak256, encodePacked } = await import('viem');
|
|
129
|
+
const { privateKeyToAccount } = await import('viem/accounts');
|
|
130
|
+
const { sepolia } = await import('viem/chains');
|
|
131
|
+
const account = privateKeyToAccount(this.config.privateKey);
|
|
132
|
+
const publicClient = createPublicClient({ chain: sepolia, transport: http(this.config.rpcUrl) });
|
|
133
|
+
const walletClient = createWalletClient({ account, chain: sepolia, transport: http(this.config.rpcUrl) });
|
|
134
|
+
const cofheClient = createCofheClient(createCofheConfig({ supportedChains: [sepolia] }));
|
|
135
|
+
await cofheClient.connect(publicClient, walletClient);
|
|
136
|
+
onProgress?.('encrypting');
|
|
137
|
+
const amountsWei = recipients.map((r) => parseEther(r.amount));
|
|
138
|
+
const encrypted = await cofheClient
|
|
139
|
+
.encryptInputs(amountsWei.map((w) => Encryptable.uint64(w)))
|
|
140
|
+
.execute();
|
|
141
|
+
const encryptedAmounts = encrypted.map((e) => ({
|
|
142
|
+
ctHash: BigInt(e.ctHash ?? 0),
|
|
143
|
+
securityZone: e.securityZone ?? 0,
|
|
144
|
+
utype: e.utype ?? 5,
|
|
145
|
+
signature: e.signature ?? '0x',
|
|
146
|
+
}));
|
|
147
|
+
const total = amountsWei.reduce((sum, w) => sum + w, 0n);
|
|
148
|
+
const salt = keccak256(encodePacked(['address', 'uint256'], [account.address, BigInt(Date.now())]));
|
|
149
|
+
const createBatchAbi = [{
|
|
150
|
+
name: 'createBatch',
|
|
151
|
+
type: 'function',
|
|
152
|
+
stateMutability: 'payable',
|
|
153
|
+
inputs: [
|
|
154
|
+
{ name: '_recipients', type: 'address[]' },
|
|
155
|
+
{ name: '_encryptedAmounts', type: 'tuple[]', components: [
|
|
156
|
+
{ name: 'ctHash', type: 'uint256' }, { name: 'securityZone', type: 'uint8' },
|
|
157
|
+
{ name: 'utype', type: 'uint8' }, { name: 'signature', type: 'bytes' },
|
|
158
|
+
] },
|
|
159
|
+
{ name: '_ethAmounts', type: 'uint256[]' },
|
|
160
|
+
{ name: '_salt', type: 'bytes32' },
|
|
161
|
+
{ name: '_memo', type: 'string' },
|
|
162
|
+
],
|
|
163
|
+
outputs: [{ name: 'batchId', type: 'bytes32' }],
|
|
164
|
+
}];
|
|
165
|
+
onProgress?.('submitting');
|
|
166
|
+
const txHash = await walletClient.writeContract({
|
|
167
|
+
address: BATCH_CIPHER_ADDRESS,
|
|
168
|
+
abi: createBatchAbi,
|
|
169
|
+
functionName: 'createBatch',
|
|
170
|
+
args: [
|
|
171
|
+
recipients.map((r) => r.address),
|
|
172
|
+
encryptedAmounts,
|
|
173
|
+
amountsWei,
|
|
174
|
+
salt,
|
|
175
|
+
memo,
|
|
176
|
+
],
|
|
177
|
+
value: total,
|
|
178
|
+
});
|
|
179
|
+
onProgress?.('confirming');
|
|
180
|
+
const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash });
|
|
181
|
+
return {
|
|
182
|
+
txHash,
|
|
183
|
+
recipientCount: recipients.length,
|
|
184
|
+
memo,
|
|
185
|
+
blockNumber: receipt.blockNumber,
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Verify a webhook event signature.
|
|
190
|
+
*
|
|
191
|
+
* `CipherPayWebhooks` signs every delivery as `HMAC-SHA256(secret, rawBody)`
|
|
192
|
+
* and sends the hex digest in the `X-CipherPay-Signature` header. This
|
|
193
|
+
* recomputes the digest and compares it to the received one in constant
|
|
194
|
+
* time, so a merchant can reject forged or tampered webhook calls.
|
|
195
|
+
*
|
|
196
|
+
* @param payload the exact raw request body that was signed
|
|
197
|
+
* @param signature the hex digest from the `X-CipherPay-Signature` header
|
|
198
|
+
* @param secret the shared webhook secret (`whsec_...`)
|
|
199
|
+
*/
|
|
200
|
+
static verifyWebhook(payload, signature, secret) {
|
|
201
|
+
if (!payload || !signature || !secret)
|
|
202
|
+
return false;
|
|
203
|
+
const expected = createHmac('sha256', secret).update(payload).digest();
|
|
204
|
+
let received;
|
|
205
|
+
try {
|
|
206
|
+
received = Buffer.from(signature, 'hex');
|
|
207
|
+
}
|
|
208
|
+
catch {
|
|
209
|
+
return false;
|
|
210
|
+
}
|
|
211
|
+
// timingSafeEqual throws on length mismatch — guard before comparing.
|
|
212
|
+
if (received.length !== expected.length)
|
|
213
|
+
return false;
|
|
214
|
+
return timingSafeEqual(expected, received);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
//# sourceMappingURL=CipherPay.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CipherPay.js","sourceRoot":"","sources":["../src/CipherPay.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* useCheckout — React hook for paying a CipherPay invoice with an FHE-encrypted amount.
|
|
3
|
+
*
|
|
4
|
+
* Render it inside a wagmi `<WagmiProvider>` (the consuming app supplies the
|
|
5
|
+
* provider; `wagmi` and `viem` are peer dependencies of this SDK):
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* import { useCheckout } from 'cipherpay-sdk/react';
|
|
9
|
+
*
|
|
10
|
+
* function PayButton({ invoiceHash }: { invoiceHash: string }) {
|
|
11
|
+
* const { pay, status, txHash, error } = useCheckout(invoiceHash);
|
|
12
|
+
* return (
|
|
13
|
+
* <button onClick={() => pay({ amount: '0.01' })} disabled={status !== 'idle'}>
|
|
14
|
+
* {status === 'encrypting' ? 'Encrypting…' : 'Pay with CipherPay'}
|
|
15
|
+
* </button>
|
|
16
|
+
* );
|
|
17
|
+
* }
|
|
18
|
+
*
|
|
19
|
+
* The hook runs the full FHE payment flow:
|
|
20
|
+
* 1. CoFHE SDK encrypts the amount client-side (TFHE + ZK proof)
|
|
21
|
+
* 2. Contract call — payInvoice / payInvoiceShielded / claimAnonymously
|
|
22
|
+
* 3. Wait for the transaction receipt
|
|
23
|
+
*/
|
|
24
|
+
import type { CheckoutState } from '../types';
|
|
25
|
+
export declare function useCheckout(invoiceHash: string): CheckoutState;
|
|
26
|
+
//# sourceMappingURL=useCheckout.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useCheckout.d.ts","sourceRoot":"","sources":["../../src/hooks/useCheckout.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAIH,OAAO,KAAK,EAAE,aAAa,EAA+C,MAAM,UAAU,CAAC;AAoB3F,wBAAgB,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,aAAa,CA0G9D"}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* useCheckout — React hook for paying a CipherPay invoice with an FHE-encrypted amount.
|
|
3
|
+
*
|
|
4
|
+
* Render it inside a wagmi `<WagmiProvider>` (the consuming app supplies the
|
|
5
|
+
* provider; `wagmi` and `viem` are peer dependencies of this SDK):
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* import { useCheckout } from 'cipherpay-sdk/react';
|
|
9
|
+
*
|
|
10
|
+
* function PayButton({ invoiceHash }: { invoiceHash: string }) {
|
|
11
|
+
* const { pay, status, txHash, error } = useCheckout(invoiceHash);
|
|
12
|
+
* return (
|
|
13
|
+
* <button onClick={() => pay({ amount: '0.01' })} disabled={status !== 'idle'}>
|
|
14
|
+
* {status === 'encrypting' ? 'Encrypting…' : 'Pay with CipherPay'}
|
|
15
|
+
* </button>
|
|
16
|
+
* );
|
|
17
|
+
* }
|
|
18
|
+
*
|
|
19
|
+
* The hook runs the full FHE payment flow:
|
|
20
|
+
* 1. CoFHE SDK encrypts the amount client-side (TFHE + ZK proof)
|
|
21
|
+
* 2. Contract call — payInvoice / payInvoiceShielded / claimAnonymously
|
|
22
|
+
* 3. Wait for the transaction receipt
|
|
23
|
+
*/
|
|
24
|
+
import { useState, useCallback, useRef } from 'react';
|
|
25
|
+
import { useAccount, usePublicClient, useWalletClient } from 'wagmi';
|
|
26
|
+
const CIPHERPAY_FHE_ADDRESS = '0x305eF265BD964fBe34913E70Ef6AA8951e6b662e';
|
|
27
|
+
const ENCRYPTED_PAYMENT = {
|
|
28
|
+
name: '_encryptedPayment', type: 'tuple', components: [
|
|
29
|
+
{ name: 'ctHash', type: 'uint256' }, { name: 'securityZone', type: 'uint8' },
|
|
30
|
+
{ name: 'utype', type: 'uint8' }, { name: 'signature', type: 'bytes' },
|
|
31
|
+
],
|
|
32
|
+
};
|
|
33
|
+
const PAY_ABI = [
|
|
34
|
+
{ name: 'payInvoice', type: 'function', stateMutability: 'payable',
|
|
35
|
+
inputs: [{ name: '_invoiceHash', type: 'bytes32' }, ENCRYPTED_PAYMENT], outputs: [] },
|
|
36
|
+
{ name: 'payInvoiceShielded', type: 'function', stateMutability: 'nonpayable',
|
|
37
|
+
inputs: [{ name: '_invoiceHash', type: 'bytes32' }, ENCRYPTED_PAYMENT, { name: '_maxDebit', type: 'uint256' }], outputs: [] },
|
|
38
|
+
{ name: 'claimAnonymously', type: 'function', stateMutability: 'payable',
|
|
39
|
+
inputs: [{ name: '_invoiceHash', type: 'bytes32' }, ENCRYPTED_PAYMENT, { name: '_nullifier', type: 'bytes32' }], outputs: [] },
|
|
40
|
+
];
|
|
41
|
+
export function useCheckout(invoiceHash) {
|
|
42
|
+
const { address } = useAccount();
|
|
43
|
+
const publicClient = usePublicClient();
|
|
44
|
+
const { data: walletClient } = useWalletClient();
|
|
45
|
+
const [status, setStatus] = useState('idle');
|
|
46
|
+
const [error, setError] = useState(null);
|
|
47
|
+
const [txHash, setTxHash] = useState(null);
|
|
48
|
+
const [blockNumber, setBlock] = useState(null);
|
|
49
|
+
// The CoFHE client is created+connected once on the first pay() and reused.
|
|
50
|
+
const cofheRef = useRef(null);
|
|
51
|
+
const pay = useCallback(async (opts) => {
|
|
52
|
+
if (!walletClient || !publicClient || !address) {
|
|
53
|
+
const msg = 'Wallet not connected — render useCheckout inside a wagmi <WagmiProvider> and connect a wallet first.';
|
|
54
|
+
setError(msg);
|
|
55
|
+
setStatus('error');
|
|
56
|
+
throw new Error(msg);
|
|
57
|
+
}
|
|
58
|
+
setStatus('initializing_fhe');
|
|
59
|
+
setError(null);
|
|
60
|
+
setTxHash(null);
|
|
61
|
+
setBlock(null);
|
|
62
|
+
try {
|
|
63
|
+
const amount = opts?.amount ?? '0';
|
|
64
|
+
const shielded = opts?.shielded ?? false;
|
|
65
|
+
const anonymous = opts?.anonymous ?? false;
|
|
66
|
+
const { Encryptable } = await import('@cofhe/sdk');
|
|
67
|
+
const { parseEther, keccak256, encodePacked } = await import('viem');
|
|
68
|
+
// Lazily create + connect the CoFHE client (TFHE keys + ZK proving).
|
|
69
|
+
if (!cofheRef.current) {
|
|
70
|
+
const { createCofheConfig, createCofheClient } = await import('@cofhe/sdk/web');
|
|
71
|
+
const { sepolia } = await import('@cofhe/sdk/chains');
|
|
72
|
+
const client = createCofheClient(createCofheConfig({
|
|
73
|
+
supportedChains: [sepolia],
|
|
74
|
+
useWorkers: typeof SharedArrayBuffer !== 'undefined',
|
|
75
|
+
}));
|
|
76
|
+
await client.connect(publicClient, walletClient);
|
|
77
|
+
cofheRef.current = client;
|
|
78
|
+
}
|
|
79
|
+
const cofhe = cofheRef.current;
|
|
80
|
+
setStatus('encrypting');
|
|
81
|
+
const amountWei = parseEther(amount);
|
|
82
|
+
const [enc] = await cofhe
|
|
83
|
+
.encryptInputs([Encryptable.uint64(amountWei)])
|
|
84
|
+
.onStep((step) => opts?.onProgress?.(step))
|
|
85
|
+
.execute();
|
|
86
|
+
const encryptedPayment = {
|
|
87
|
+
ctHash: BigInt(enc.ctHash ?? 0),
|
|
88
|
+
securityZone: enc.securityZone ?? 0,
|
|
89
|
+
utype: enc.utype ?? 5,
|
|
90
|
+
signature: enc.signature ?? '0x',
|
|
91
|
+
};
|
|
92
|
+
setStatus('awaiting_signature');
|
|
93
|
+
const functionName = anonymous ? 'claimAnonymously' : shielded ? 'payInvoiceShielded' : 'payInvoice';
|
|
94
|
+
const nullifier = opts?.nullifier
|
|
95
|
+
?? keccak256(encodePacked(['address', 'bytes32'], [address, invoiceHash]));
|
|
96
|
+
const args = anonymous
|
|
97
|
+
? [invoiceHash, encryptedPayment, nullifier]
|
|
98
|
+
: shielded
|
|
99
|
+
? [invoiceHash, encryptedPayment, amountWei]
|
|
100
|
+
: [invoiceHash, encryptedPayment];
|
|
101
|
+
setStatus('submitting');
|
|
102
|
+
const hash = await walletClient.writeContract({
|
|
103
|
+
address: CIPHERPAY_FHE_ADDRESS,
|
|
104
|
+
abi: PAY_ABI,
|
|
105
|
+
functionName,
|
|
106
|
+
args,
|
|
107
|
+
value: anonymous || shielded ? 0n : amountWei,
|
|
108
|
+
account: address,
|
|
109
|
+
chain: walletClient.chain,
|
|
110
|
+
});
|
|
111
|
+
setTxHash(hash);
|
|
112
|
+
setStatus('confirming');
|
|
113
|
+
const receipt = await publicClient.waitForTransactionReceipt({ hash });
|
|
114
|
+
setBlock(receipt.blockNumber);
|
|
115
|
+
setStatus('success');
|
|
116
|
+
return {
|
|
117
|
+
txHash: hash,
|
|
118
|
+
invoiceId: invoiceHash,
|
|
119
|
+
amount,
|
|
120
|
+
shielded,
|
|
121
|
+
anonymous,
|
|
122
|
+
blockNumber: receipt.blockNumber,
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
catch (err) {
|
|
126
|
+
const msg = err?.message || 'Payment failed';
|
|
127
|
+
setError(msg);
|
|
128
|
+
setStatus('error');
|
|
129
|
+
throw err;
|
|
130
|
+
}
|
|
131
|
+
}, [invoiceHash, address, publicClient, walletClient]);
|
|
132
|
+
return { status, error, txHash, blockNumber, pay };
|
|
133
|
+
}
|
|
134
|
+
//# sourceMappingURL=useCheckout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useCheckout.js","sourceRoot":"","sources":["../../src/hooks/useCheckout.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* useShieldedBalance — React hook for CipherPay shielded balance management.
|
|
3
|
+
*
|
|
4
|
+
* @example
|
|
5
|
+
* const { balance, deposit, withdraw, isDepositing } = useShieldedBalance();
|
|
6
|
+
*
|
|
7
|
+
* // Deposit 0.01 ETH into shielded pool
|
|
8
|
+
* await deposit('0.01');
|
|
9
|
+
*
|
|
10
|
+
* // Withdraw 0.005 ETH back to wallet
|
|
11
|
+
* await withdraw('0.005');
|
|
12
|
+
*/
|
|
13
|
+
export declare function useShieldedBalance(): {
|
|
14
|
+
balance: string;
|
|
15
|
+
deposit: (amountEth: string) => Promise<`0x${string}`>;
|
|
16
|
+
withdraw: (amountEth: string) => Promise<`0x${string}`>;
|
|
17
|
+
refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<bigint, import("viem").ReadContractErrorType>>;
|
|
18
|
+
};
|
|
19
|
+
//# sourceMappingURL=useShieldedBalance.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useShieldedBalance.d.ts","sourceRoot":"","sources":["../../src/hooks/useShieldedBalance.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAeH,wBAAgB,kBAAkB;;yBAec,MAAM;0BAYL,MAAM;;EAatD"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* useShieldedBalance — React hook for CipherPay shielded balance management.
|
|
3
|
+
*
|
|
4
|
+
* @example
|
|
5
|
+
* const { balance, deposit, withdraw, isDepositing } = useShieldedBalance();
|
|
6
|
+
*
|
|
7
|
+
* // Deposit 0.01 ETH into shielded pool
|
|
8
|
+
* await deposit('0.01');
|
|
9
|
+
*
|
|
10
|
+
* // Withdraw 0.005 ETH back to wallet
|
|
11
|
+
* await withdraw('0.005');
|
|
12
|
+
*/
|
|
13
|
+
import { useCallback } from 'react';
|
|
14
|
+
import { useAccount, useReadContract, useWriteContract, usePublicClient } from 'wagmi';
|
|
15
|
+
import { parseEther, formatEther } from 'viem';
|
|
16
|
+
// Import from the app's contract config
|
|
17
|
+
const CIPHERPAY_FHE_ADDRESS = '0x305eF265BD964fBe34913E70Ef6AA8951e6b662e';
|
|
18
|
+
const SHIELDED_ABI = [
|
|
19
|
+
{ name: 'depositShielded', type: 'function', stateMutability: 'payable', inputs: [], outputs: [] },
|
|
20
|
+
{ name: 'withdrawShielded', type: 'function', stateMutability: 'nonpayable', inputs: [{ name: '_amount', type: 'uint256' }], outputs: [] },
|
|
21
|
+
{ name: 'shieldedBalance', type: 'function', stateMutability: 'view', inputs: [{ name: '', type: 'address' }], outputs: [{ name: '', type: 'uint256' }] },
|
|
22
|
+
];
|
|
23
|
+
export function useShieldedBalance() {
|
|
24
|
+
const { address } = useAccount();
|
|
25
|
+
const publicClient = usePublicClient();
|
|
26
|
+
const { writeContractAsync } = useWriteContract();
|
|
27
|
+
const { data: balanceRaw, refetch } = useReadContract({
|
|
28
|
+
address: CIPHERPAY_FHE_ADDRESS,
|
|
29
|
+
abi: SHIELDED_ABI,
|
|
30
|
+
functionName: 'shieldedBalance',
|
|
31
|
+
args: [address],
|
|
32
|
+
query: { enabled: !!address },
|
|
33
|
+
});
|
|
34
|
+
const balance = balanceRaw ? formatEther(balanceRaw) : '0';
|
|
35
|
+
const deposit = useCallback(async (amountEth) => {
|
|
36
|
+
const txHash = await writeContractAsync({
|
|
37
|
+
address: CIPHERPAY_FHE_ADDRESS,
|
|
38
|
+
abi: SHIELDED_ABI,
|
|
39
|
+
functionName: 'depositShielded',
|
|
40
|
+
value: parseEther(amountEth),
|
|
41
|
+
});
|
|
42
|
+
await publicClient.waitForTransactionReceipt({ hash: txHash });
|
|
43
|
+
await refetch();
|
|
44
|
+
return txHash;
|
|
45
|
+
}, [writeContractAsync, publicClient, refetch]);
|
|
46
|
+
const withdraw = useCallback(async (amountEth) => {
|
|
47
|
+
const txHash = await writeContractAsync({
|
|
48
|
+
address: CIPHERPAY_FHE_ADDRESS,
|
|
49
|
+
abi: SHIELDED_ABI,
|
|
50
|
+
functionName: 'withdrawShielded',
|
|
51
|
+
args: [parseEther(amountEth)],
|
|
52
|
+
});
|
|
53
|
+
await publicClient.waitForTransactionReceipt({ hash: txHash });
|
|
54
|
+
await refetch();
|
|
55
|
+
return txHash;
|
|
56
|
+
}, [writeContractAsync, publicClient, refetch]);
|
|
57
|
+
return { balance, deposit, withdraw, refetch };
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=useShieldedBalance.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useShieldedBalance.js","sourceRoot":"","sources":["../../src/hooks/useShieldedBalance.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* cipherpay-sdk
|
|
3
|
+
*
|
|
4
|
+
* Confidential payroll & payments SDK for CipherPay on Fhenix FHE.
|
|
5
|
+
*
|
|
6
|
+
* Node / server entry. React hooks are in the 'cipherpay-sdk/react' subpath.
|
|
7
|
+
*
|
|
8
|
+
* Run a confidential payroll:
|
|
9
|
+
* const cp = new CipherPay({ rpcUrl: 'https://...', privateKey: '0x...' });
|
|
10
|
+
* await cp.runPayroll({
|
|
11
|
+
* recipients: [
|
|
12
|
+
* { address: '0x...', amount: '2500.00' },
|
|
13
|
+
* { address: '0x...', amount: '1800.00' },
|
|
14
|
+
* ],
|
|
15
|
+
* memo: 'April Payroll',
|
|
16
|
+
* });
|
|
17
|
+
*
|
|
18
|
+
* Charge a single invoice:
|
|
19
|
+
* await cp.charge({ invoiceId: '0x...', amount: '0.01' });
|
|
20
|
+
*
|
|
21
|
+
* Relay on-chain events to a webhook endpoint:
|
|
22
|
+
* new CipherPayWebhooks({ rpcUrl, endpoint, secret }).start();
|
|
23
|
+
*/
|
|
24
|
+
export { CipherPay } from './CipherPay';
|
|
25
|
+
export { CipherPayWebhooks } from './webhooks';
|
|
26
|
+
export type { ChargeOptions, ChargeResult, PayrollOptions, PayrollRecipient, PayrollResult, CheckoutState, CheckoutStatus, WebhookEvent, InvoiceType, CipherPayConfig, } from './types';
|
|
27
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAc,aAAa,CAAC;AAChD,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC/C,YAAY,EACV,aAAa,EACb,YAAY,EACZ,cAAc,EACd,gBAAgB,EAChB,aAAa,EACb,aAAa,EACb,cAAc,EACd,YAAY,EACZ,WAAW,EACX,eAAe,GAChB,MAAM,SAAS,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* cipherpay-sdk
|
|
3
|
+
*
|
|
4
|
+
* Confidential payroll & payments SDK for CipherPay on Fhenix FHE.
|
|
5
|
+
*
|
|
6
|
+
* Node / server entry. React hooks are in the 'cipherpay-sdk/react' subpath.
|
|
7
|
+
*
|
|
8
|
+
* Run a confidential payroll:
|
|
9
|
+
* const cp = new CipherPay({ rpcUrl: 'https://...', privateKey: '0x...' });
|
|
10
|
+
* await cp.runPayroll({
|
|
11
|
+
* recipients: [
|
|
12
|
+
* { address: '0x...', amount: '2500.00' },
|
|
13
|
+
* { address: '0x...', amount: '1800.00' },
|
|
14
|
+
* ],
|
|
15
|
+
* memo: 'April Payroll',
|
|
16
|
+
* });
|
|
17
|
+
*
|
|
18
|
+
* Charge a single invoice:
|
|
19
|
+
* await cp.charge({ invoiceId: '0x...', amount: '0.01' });
|
|
20
|
+
*
|
|
21
|
+
* Relay on-chain events to a webhook endpoint:
|
|
22
|
+
* new CipherPayWebhooks({ rpcUrl, endpoint, secret }).start();
|
|
23
|
+
*/
|
|
24
|
+
export { CipherPay } from './CipherPay';
|
|
25
|
+
export { CipherPayWebhooks } from './webhooks';
|
|
26
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAc,aAAa,CAAC;AAChD,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC"}
|
package/dist/react.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* cipherpay-sdk/react — React hooks for CipherPay.
|
|
3
|
+
*
|
|
4
|
+
* These hooks call wagmi internally, so the host app must wrap its tree in a
|
|
5
|
+
* wagmi `<WagmiProvider>`. `react`, `wagmi`, and `viem` are peer dependencies.
|
|
6
|
+
*
|
|
7
|
+
* import { useCheckout } from 'cipherpay-sdk/react';
|
|
8
|
+
*/
|
|
9
|
+
export { useCheckout } from './hooks/useCheckout';
|
|
10
|
+
export { useShieldedBalance } from './hooks/useShieldedBalance';
|
|
11
|
+
export type { CheckoutState, CheckoutStatus } from './types';
|
|
12
|
+
//# sourceMappingURL=react.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"react.d.ts","sourceRoot":"","sources":["../src/react.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAa,qBAAqB,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAChE,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC"}
|
package/dist/react.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* cipherpay-sdk/react — React hooks for CipherPay.
|
|
3
|
+
*
|
|
4
|
+
* These hooks call wagmi internally, so the host app must wrap its tree in a
|
|
5
|
+
* wagmi `<WagmiProvider>`. `react`, `wagmi`, and `viem` are peer dependencies.
|
|
6
|
+
*
|
|
7
|
+
* import { useCheckout } from 'cipherpay-sdk/react';
|
|
8
|
+
*/
|
|
9
|
+
export { useCheckout } from './hooks/useCheckout';
|
|
10
|
+
export { useShieldedBalance } from './hooks/useShieldedBalance';
|
|
11
|
+
//# sourceMappingURL=react.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"react.js","sourceRoot":"","sources":["../src/react.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAa,qBAAqB,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
export type InvoiceType = 'standard' | 'multipay' | 'recurring' | 'vesting' | 'donation' | 'batch';
|
|
2
|
+
export interface ChargeOptions {
|
|
3
|
+
invoiceId: string;
|
|
4
|
+
amount: string;
|
|
5
|
+
currency?: 'ETH';
|
|
6
|
+
shielded?: boolean;
|
|
7
|
+
anonymous?: boolean;
|
|
8
|
+
nullifier?: string;
|
|
9
|
+
onProgress?: (step: string, ctx?: Record<string, unknown>) => void;
|
|
10
|
+
}
|
|
11
|
+
export interface ChargeResult {
|
|
12
|
+
txHash: string;
|
|
13
|
+
invoiceId: string;
|
|
14
|
+
amount: string;
|
|
15
|
+
shielded: boolean;
|
|
16
|
+
anonymous: boolean;
|
|
17
|
+
blockNumber?: bigint;
|
|
18
|
+
}
|
|
19
|
+
export interface PayrollRecipient {
|
|
20
|
+
address: string;
|
|
21
|
+
amount: string;
|
|
22
|
+
}
|
|
23
|
+
export interface PayrollOptions {
|
|
24
|
+
recipients: PayrollRecipient[];
|
|
25
|
+
memo?: string;
|
|
26
|
+
onProgress?: (step: string) => void;
|
|
27
|
+
}
|
|
28
|
+
export interface PayrollResult {
|
|
29
|
+
txHash: string;
|
|
30
|
+
batchId?: string;
|
|
31
|
+
recipientCount: number;
|
|
32
|
+
memo: string;
|
|
33
|
+
blockNumber?: bigint;
|
|
34
|
+
}
|
|
35
|
+
export type CheckoutStatus = 'idle' | 'initializing_fhe' | 'encrypting' | 'awaiting_signature' | 'submitting' | 'confirming' | 'success' | 'error';
|
|
36
|
+
export interface CheckoutState {
|
|
37
|
+
status: CheckoutStatus;
|
|
38
|
+
error: string | null;
|
|
39
|
+
txHash: string | null;
|
|
40
|
+
blockNumber: bigint | null;
|
|
41
|
+
pay: (opts?: Partial<ChargeOptions>) => Promise<ChargeResult>;
|
|
42
|
+
}
|
|
43
|
+
export interface WebhookEvent {
|
|
44
|
+
type: 'invoice.paid' | 'invoice.settled' | 'invoice.cancelled' | 'anon.claimed';
|
|
45
|
+
invoiceId: string;
|
|
46
|
+
txHash: string;
|
|
47
|
+
blockNumber: number;
|
|
48
|
+
payer?: string;
|
|
49
|
+
timestamp: number;
|
|
50
|
+
}
|
|
51
|
+
export interface CipherPayConfig {
|
|
52
|
+
rpcUrl: string;
|
|
53
|
+
privateKey?: string;
|
|
54
|
+
chainId?: number;
|
|
55
|
+
contract?: string;
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,WAAW,GAAG,UAAU,GAAG,UAAU,GAAG,WAAW,GAAG,SAAS,GAAG,UAAU,GAAG,OAAO,CAAC;AAEnG,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAI,MAAM,CAAC;IACpB,MAAM,EAAO,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAI,KAAK,CAAC;IACnB,QAAQ,CAAC,EAAI,OAAO,CAAC;IACrB,SAAS,CAAC,EAAG,OAAO,CAAC;IACrB,SAAS,CAAC,EAAG,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;CACpE;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAK,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAK,MAAM,CAAC;IAClB,QAAQ,EAAG,OAAO,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAG,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAG,gBAAgB,EAAE,CAAC;IAChC,IAAI,CAAC,EAAQ,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CACrC;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAU,MAAM,CAAC;IACvB,OAAO,CAAC,EAAQ,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,IAAI,EAAY,MAAM,CAAC;IACvB,WAAW,CAAC,EAAI,MAAM,CAAC;CACxB;AAED,MAAM,MAAM,cAAc,GACtB,MAAM,GACN,kBAAkB,GAClB,YAAY,GACZ,oBAAoB,GACpB,YAAY,GACZ,YAAY,GACZ,SAAS,GACT,OAAO,CAAC;AAEZ,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAM,cAAc,CAAC;IAC3B,KAAK,EAAO,MAAM,GAAG,IAAI,CAAC;IAC1B,MAAM,EAAM,MAAM,GAAG,IAAI,CAAC;IAC1B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,GAAG,EAAS,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,KAAK,OAAO,CAAC,YAAY,CAAC,CAAC;CACtE;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAO,cAAc,GAAG,iBAAiB,GAAG,mBAAmB,GAAG,cAAc,CAAC;IACrF,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAK,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAK,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAO,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAK,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAI,MAAM,CAAC;CACrB"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CipherPayWebhooks — relay on-chain CipherPay events to HTTPS endpoints.
|
|
3
|
+
*
|
|
4
|
+
* Merchants get order confirmation like Stripe webhooks.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* const webhooks = new CipherPayWebhooks({
|
|
8
|
+
* rpcUrl: 'https://...',
|
|
9
|
+
* endpoint: 'https://my-store.com/webhooks/cipherpay',
|
|
10
|
+
* secret: 'whsec_...',
|
|
11
|
+
* });
|
|
12
|
+
*
|
|
13
|
+
* webhooks.start();
|
|
14
|
+
* // Listens to InvoicePaid, InvoiceSettled, AnonClaimSubmitted events
|
|
15
|
+
* // POSTs signed JSON to your endpoint on each event
|
|
16
|
+
*/
|
|
17
|
+
interface WebhookConfig {
|
|
18
|
+
rpcUrl: string;
|
|
19
|
+
endpoint: string;
|
|
20
|
+
secret: string;
|
|
21
|
+
contract?: string;
|
|
22
|
+
fromBlock?: bigint;
|
|
23
|
+
}
|
|
24
|
+
export declare class CipherPayWebhooks {
|
|
25
|
+
private config;
|
|
26
|
+
private running;
|
|
27
|
+
constructor(config: WebhookConfig);
|
|
28
|
+
/** Start watching for events and relaying to the webhook endpoint */
|
|
29
|
+
start(): Promise<void>;
|
|
30
|
+
stop(): void;
|
|
31
|
+
private _logToEventType;
|
|
32
|
+
private _deliver;
|
|
33
|
+
private _sign;
|
|
34
|
+
}
|
|
35
|
+
export {};
|
|
36
|
+
//# sourceMappingURL=webhooks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webhooks.d.ts","sourceRoot":"","sources":["../src/webhooks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAIH,UAAU,aAAa;IACrB,MAAM,EAAK,MAAM,CAAC;IAClB,QAAQ,EAAG,MAAM,CAAC;IAClB,MAAM,EAAK,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAID,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,MAAM,CAA0B;IACxC,OAAO,CAAC,OAAO,CAAS;gBAEZ,MAAM,EAAE,aAAa;IAUjC,qEAAqE;IAC/D,KAAK;IAsCX,IAAI;IAIJ,OAAO,CAAC,eAAe;YAUT,QAAQ;YAmBR,KAAK;CAKpB"}
|
package/dist/webhooks.js
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CipherPayWebhooks — relay on-chain CipherPay events to HTTPS endpoints.
|
|
3
|
+
*
|
|
4
|
+
* Merchants get order confirmation like Stripe webhooks.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* const webhooks = new CipherPayWebhooks({
|
|
8
|
+
* rpcUrl: 'https://...',
|
|
9
|
+
* endpoint: 'https://my-store.com/webhooks/cipherpay',
|
|
10
|
+
* secret: 'whsec_...',
|
|
11
|
+
* });
|
|
12
|
+
*
|
|
13
|
+
* webhooks.start();
|
|
14
|
+
* // Listens to InvoicePaid, InvoiceSettled, AnonClaimSubmitted events
|
|
15
|
+
* // POSTs signed JSON to your endpoint on each event
|
|
16
|
+
*/
|
|
17
|
+
const DEFAULT_CONTRACT = '0x305eF265BD964fBe34913E70Ef6AA8951e6b662e';
|
|
18
|
+
export class CipherPayWebhooks {
|
|
19
|
+
config;
|
|
20
|
+
running = false;
|
|
21
|
+
constructor(config) {
|
|
22
|
+
this.config = {
|
|
23
|
+
rpcUrl: config.rpcUrl,
|
|
24
|
+
endpoint: config.endpoint,
|
|
25
|
+
secret: config.secret,
|
|
26
|
+
contract: config.contract ?? DEFAULT_CONTRACT,
|
|
27
|
+
fromBlock: config.fromBlock ?? 0n,
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
/** Start watching for events and relaying to the webhook endpoint */
|
|
31
|
+
async start() {
|
|
32
|
+
if (this.running)
|
|
33
|
+
return;
|
|
34
|
+
this.running = true;
|
|
35
|
+
const { createPublicClient, http, parseAbi } = await import('viem');
|
|
36
|
+
const { sepolia } = await import('viem/chains');
|
|
37
|
+
const client = createPublicClient({
|
|
38
|
+
chain: sepolia,
|
|
39
|
+
transport: http(this.config.rpcUrl),
|
|
40
|
+
});
|
|
41
|
+
const abi = parseAbi([
|
|
42
|
+
'event InvoicePaid(bytes32 indexed invoiceHash, address indexed payer)',
|
|
43
|
+
'event InvoiceSettled(bytes32 indexed invoiceHash)',
|
|
44
|
+
'event InvoiceCancelled(bytes32 indexed invoiceHash)',
|
|
45
|
+
'event AnonClaimSubmitted(bytes32 indexed invoiceHash, bytes32 indexed nullifier)',
|
|
46
|
+
]);
|
|
47
|
+
client.watchContractEvent({
|
|
48
|
+
address: this.config.contract,
|
|
49
|
+
abi,
|
|
50
|
+
onLogs: async (logs) => {
|
|
51
|
+
for (const log of logs) {
|
|
52
|
+
const event = {
|
|
53
|
+
type: this._logToEventType(log.eventName),
|
|
54
|
+
invoiceId: log.args.invoiceHash ?? '',
|
|
55
|
+
txHash: log.transactionHash ?? '',
|
|
56
|
+
blockNumber: Number(log.blockNumber ?? 0),
|
|
57
|
+
payer: log.args.payer,
|
|
58
|
+
timestamp: Date.now(),
|
|
59
|
+
};
|
|
60
|
+
await this._deliver(event);
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
stop() {
|
|
66
|
+
this.running = false;
|
|
67
|
+
}
|
|
68
|
+
_logToEventType(name) {
|
|
69
|
+
const map = {
|
|
70
|
+
InvoicePaid: 'invoice.paid',
|
|
71
|
+
InvoiceSettled: 'invoice.settled',
|
|
72
|
+
InvoiceCancelled: 'invoice.cancelled',
|
|
73
|
+
AnonClaimSubmitted: 'anon.claimed',
|
|
74
|
+
};
|
|
75
|
+
return map[name ?? ''] ?? 'invoice.paid';
|
|
76
|
+
}
|
|
77
|
+
async _deliver(event) {
|
|
78
|
+
const body = JSON.stringify(event);
|
|
79
|
+
const sig = await this._sign(body);
|
|
80
|
+
try {
|
|
81
|
+
await fetch(this.config.endpoint, {
|
|
82
|
+
method: 'POST',
|
|
83
|
+
headers: {
|
|
84
|
+
'Content-Type': 'application/json',
|
|
85
|
+
'X-CipherPay-Signature': sig,
|
|
86
|
+
'X-CipherPay-Timestamp': String(event.timestamp),
|
|
87
|
+
},
|
|
88
|
+
body,
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
catch (err) {
|
|
92
|
+
console.error('[CipherPay Webhooks] Delivery failed:', err);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
async _sign(payload) {
|
|
96
|
+
// HMAC-SHA256 signature for webhook verification
|
|
97
|
+
const { createHmac } = await import('crypto');
|
|
98
|
+
return createHmac('sha256', this.config.secret).update(payload).digest('hex');
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=webhooks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webhooks.js","sourceRoot":"","sources":["../src/webhooks.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "cipherpay-sdk",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Confidential payroll & payments SDK for CipherPay on Fhenix FHE — encrypted payouts, webhooks, and React hooks.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"repository": "https://github.com/kravadk/cipherpay",
|
|
7
|
+
"type": "module",
|
|
8
|
+
"files": ["dist", "README.md"],
|
|
9
|
+
"main": "./dist/index.js",
|
|
10
|
+
"module": "./dist/index.js",
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"exports": {
|
|
13
|
+
".": {
|
|
14
|
+
"types": "./dist/index.d.ts",
|
|
15
|
+
"import": "./dist/index.js"
|
|
16
|
+
},
|
|
17
|
+
"./react": {
|
|
18
|
+
"types": "./dist/react.d.ts",
|
|
19
|
+
"import": "./dist/react.js"
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"scripts": {
|
|
23
|
+
"build": "tsc -p tsconfig.json",
|
|
24
|
+
"prepublishOnly": "npm run build"
|
|
25
|
+
},
|
|
26
|
+
"keywords": [
|
|
27
|
+
"fhe",
|
|
28
|
+
"fhenix",
|
|
29
|
+
"cofhe",
|
|
30
|
+
"confidential",
|
|
31
|
+
"payroll",
|
|
32
|
+
"payments",
|
|
33
|
+
"ethereum",
|
|
34
|
+
"web3"
|
|
35
|
+
],
|
|
36
|
+
"engines": {
|
|
37
|
+
"node": ">=18"
|
|
38
|
+
},
|
|
39
|
+
"peerDependencies": {
|
|
40
|
+
"@cofhe/sdk": ">=0.5.0",
|
|
41
|
+
"react": ">=18.0.0",
|
|
42
|
+
"viem": ">=2.0.0",
|
|
43
|
+
"wagmi": ">=2.0.0"
|
|
44
|
+
},
|
|
45
|
+
"peerDependenciesMeta": {
|
|
46
|
+
"react": { "optional": true },
|
|
47
|
+
"wagmi": { "optional": true }
|
|
48
|
+
},
|
|
49
|
+
"devDependencies": {
|
|
50
|
+
"@types/node": "^22.14.0",
|
|
51
|
+
"@types/react": "^19.0.0",
|
|
52
|
+
"typescript": "~5.8.2"
|
|
53
|
+
}
|
|
54
|
+
}
|