Skip to content

Commit 3ab4a31

Browse files
authored
Merge pull request #9 from oak-network/docs/working-with-privy
docs: Privy wallet integration details in contracts SDK documentation
2 parents 1e12aee + b24c13b commit 3ab4a31

14 files changed

Lines changed: 229 additions & 121 deletions

‎docs/contracts-sdk/all-or-nothing.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ interface TieredReward {
8282
### Add rewards and pledge
8383

8484
```typescript
85-
import { keccak256, toHex } from '@oaknetwork/contracts';
85+
import { keccak256, toHex } from '@oaknetwork/contracts-sdk';
8686

8787
const rewardName = keccak256(toHex('early-bird'));
8888
const reward = {

‎docs/contracts-sdk/campaign-info-factory.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ import {
6565
toHex,
6666
getCurrentTimestamp,
6767
addDays,
68-
} from '@oaknetwork/contracts';
68+
} from '@oaknetwork/contracts-sdk';
6969

7070
const PLATFORM_HASH = keccak256(toHex('my-platform'));
7171
const CURRENCY = toHex('USD', { size: 32 });

‎docs/contracts-sdk/campaign-info.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ console.log('Identifier:', config.identifierHash);
9898
### Update campaign deadline
9999

100100
```typescript
101-
import { addDays, getCurrentTimestamp } from '@oaknetwork/contracts';
101+
import { addDays, getCurrentTimestamp } from '@oaknetwork/contracts-sdk';
102102

103103
const newDeadline = addDays(getCurrentTimestamp(), 60);
104104
const txHash = await ci.updateDeadline(newDeadline);
@@ -108,7 +108,7 @@ await oak.waitForReceipt(txHash);
108108
### Pause and cancel
109109

110110
```typescript
111-
import { toHex } from '@oaknetwork/contracts';
111+
import { toHex } from '@oaknetwork/contracts-sdk';
112112

113113
// Pause
114114
const pauseTx = await ci.pauseCampaign(toHex('Maintenance window', { size: 32 }));

‎docs/contracts-sdk/client.md‎

Lines changed: 92 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@
77
Full read/write access using a raw private key. Suitable for backend services and scripts.
88

99
```typescript
10-
import { createOakContractsClient, CHAIN_IDS } from '@oaknetwork/contracts';
10+
import { createOakContractsClient, CHAIN_IDS } from '@oaknetwork/contracts-sdk';
1111

1212
const oak = createOakContractsClient({
13-
chainId: CHAIN_IDS.CELO_TESTNET_SEPOLIA,
14-
rpcUrl: 'https://forno.celo-sepolia.celo-testnet.org',
13+
chainId: CHAIN_IDS.CELO_TESTNET_SEPOLIA,
14+
rpcUrl: 'https://forno.celo-sepolia.celo-testnet.org',
1515
privateKey: '0x...', // 0x-prefixed 32-byte hex string
1616
});
1717

@@ -20,48 +20,48 @@ const admin = await gp.getProtocolAdminAddress(); // read
2020
await gp.enlistPlatform(hash, adminAddr, fee, adapter); // write — uses client key
2121
```
2222

23-
| Field | Type | Required | Description |
24-
|---|---|---|---|
25-
| `chainId` | `number` | Yes | Numeric chain ID (use `CHAIN_IDS.*` constants) |
26-
| `rpcUrl` | `string` | Yes | RPC endpoint URL for the chain |
27-
| `privateKey` | `` `0x${string}` `` | Yes | 0x-prefixed private key for the signer |
28-
| `options` | `Partial<OakContractsClientOptions>` | No | Client-level overrides |
23+
| Field | Type | Required | Description |
24+
| ------------ | ------------------------------------ | -------- | ---------------------------------------------- |
25+
| `chainId` | `number` | Yes | Numeric chain ID (use `CHAIN_IDS.*` constants) |
26+
| `rpcUrl` | `string` | Yes | RPC endpoint URL for the chain |
27+
| `privateKey` | `` `0x${string}` `` | Yes | 0x-prefixed private key for the signer |
28+
| `options` | `Partial<OakContractsClientOptions>` | No | Client-level overrides |
2929

3030
## Pattern 2 — Read-only (`chainId` + `rpcUrl`, no `privateKey`)
3131

3232
No private key required. All read methods work normally; write and simulate methods throw immediately — no RPC call is made. The error is thrown by `requireSigner()`; the message starts with `No signer configured.` and explains how to pass a client key, full-config signer, or per-entity signer (for example `oak.globalParams(address, { signer })`).
3333

3434
```typescript
35-
import { createOakContractsClient, CHAIN_IDS } from '@oaknetwork/contracts';
35+
import { createOakContractsClient, CHAIN_IDS } from '@oaknetwork/contracts-sdk';
3636

3737
const oak = createOakContractsClient({
3838
chainId: CHAIN_IDS.CELO_TESTNET_SEPOLIA,
39-
rpcUrl: 'https://forno.celo-sepolia.celo-testnet.org',
39+
rpcUrl: 'https://forno.celo-sepolia.celo-testnet.org',
4040
});
4141

4242
const gp = oak.globalParams('0x...');
4343
const admin = await gp.getProtocolAdminAddress(); // reads work fine
4444
await gp.transferOwnership('0x...'); // throws (no signer — see requireSigner message)
4545
```
4646

47-
| Field | Type | Required | Description |
48-
|---|---|---|---|
49-
| `chainId` | `number` | Yes | Numeric chain ID (use `CHAIN_IDS.*` constants) |
50-
| `rpcUrl` | `string` | Yes | RPC endpoint URL for the chain |
51-
| `options` | `Partial<OakContractsClientOptions>` | No | Client-level overrides |
47+
| Field | Type | Required | Description |
48+
| --------- | ------------------------------------ | -------- | ---------------------------------------------- |
49+
| `chainId` | `number` | Yes | Numeric chain ID (use `CHAIN_IDS.*` constants) |
50+
| `rpcUrl` | `string` | Yes | RPC endpoint URL for the chain |
51+
| `options` | `Partial<OakContractsClientOptions>` | No | Client-level overrides |
5252

5353
## Pattern 3 — Per-entity signer override
5454

5555
Pass a signer when creating an entity. Every write and simulate call on that entity uses the provided signer — you do not pass it again on each call. Use this when the signer is resolved **after** the client is created (browser wallets, Privy, etc.).
5656

5757
```typescript
58-
import { createOakContractsClient, createWallet, CHAIN_IDS } from '@oaknetwork/contracts';
58+
import { createOakContractsClient, createWallet, CHAIN_IDS } from '@oaknetwork/contracts-sdk';
5959

6060
const RPC_URL = 'https://forno.celo-sepolia.celo-testnet.org';
6161

6262
const oak = createOakContractsClient({
6363
chainId: CHAIN_IDS.CELO_TESTNET_SEPOLIA,
64-
rpcUrl: RPC_URL,
64+
rpcUrl: RPC_URL,
6565
});
6666

6767
// Resolve signer after wallet connect
@@ -108,23 +108,23 @@ import {
108108
http,
109109
getChainFromId,
110110
CHAIN_IDS,
111-
} from '@oaknetwork/contracts';
111+
} from '@oaknetwork/contracts-sdk';
112112

113113
const RPC_URL = 'https://forno.celo-sepolia.celo-testnet.org';
114114

115-
const chain = getChainFromId(CHAIN_IDS.CELO_TESTNET_SEPOLIA);
115+
const chain = getChainFromId(CHAIN_IDS.CELO_TESTNET_SEPOLIA);
116116
const provider = createPublicClient({ chain, transport: http(RPC_URL) });
117-
const signer = createWalletClient({ account, chain, transport: http(RPC_URL) });
117+
const signer = createWalletClient({ account, chain, transport: http(RPC_URL) });
118118

119119
const oak = createOakContractsClient({ chain, provider, signer });
120120
```
121121

122-
| Field | Type | Required | Description |
123-
|---|---|---|---|
124-
| `chain` | `number \| Chain` | Yes | Numeric chain ID or viem `Chain` object |
125-
| `provider` | `PublicClient` | Yes | Viem `PublicClient` for on-chain reads |
126-
| `signer` | `WalletClient` | Yes | Viem `WalletClient` with an attached account |
127-
| `options` | `Partial<OakContractsClientOptions>` | No | Client-level overrides |
122+
| Field | Type | Required | Description |
123+
| ---------- | ------------------------------------ | -------- | -------------------------------------------- |
124+
| `chain` | `number \| Chain` | Yes | Numeric chain ID or viem `Chain` object |
125+
| `provider` | `PublicClient` | Yes | Viem `PublicClient` for on-chain reads |
126+
| `signer` | `WalletClient` | Yes | Viem `WalletClient` with an attached account |
127+
| `options` | `Partial<OakContractsClientOptions>` | No | Client-level overrides |
128128

129129
### Browser wallet with full configuration
130130

@@ -137,34 +137,77 @@ import {
137137
getSigner,
138138
getChainFromId,
139139
CHAIN_IDS,
140-
} from '@oaknetwork/contracts';
140+
} from '@oaknetwork/contracts-sdk';
141141

142-
const chain = getChainFromId(CHAIN_IDS.CELO_TESTNET_SEPOLIA);
142+
const chain = getChainFromId(CHAIN_IDS.CELO_TESTNET_SEPOLIA);
143143
const provider = createBrowserProvider(window.ethereum, chain);
144-
const signer = await getSigner(window.ethereum, chain);
144+
const signer = await getSigner(window.ethereum, chain);
145+
146+
const oak = createOakContractsClient({ chain, provider, signer });
147+
```
148+
149+
### Privy wallet with full configuration
150+
151+
[Privy](https://www.privy.io/) embedded wallets expose an EIP-1193 provider. Pass that provider to viem's `custom` transport for both `createPublicClient` and `createWalletClient`, then pass `chain`, `provider`, and `signer` into `createOakContractsClient`—the same pattern as [Browser wallet with full configuration](#browser-wallet-with-full-configuration) above.
152+
153+
The snippet uses the `useWallets` hook from `@privy-io/react-auth` to pick a wallet; replace that with whatever wallet selection logic your app uses.
154+
155+
```typescript
156+
import {
157+
createOakContractsClient,
158+
createPublicClient,
159+
createWalletClient,
160+
custom,
161+
getChainFromId,
162+
CHAIN_IDS,
163+
} from '@oaknetwork/contracts-sdk';
164+
import { useWallets } from '@privy-io/react-auth';
165+
166+
const { wallets } = useWallets();
167+
const wallet = wallets[0]; // or select by address / connector
168+
169+
const chain = getChainFromId(CHAIN_IDS.CELO_TESTNET_SEPOLIA);
170+
await wallet.switchChain(chain.id); // ensure the wallet is on this chain
171+
172+
const ethereumProvider = await wallet.getEthereumProvider();
173+
174+
const provider = createPublicClient({
175+
chain,
176+
transport: custom(ethereumProvider),
177+
});
178+
179+
const signer = createWalletClient({
180+
chain,
181+
transport: custom(ethereumProvider),
182+
account: wallet.address as `0x${string}`,
183+
});
145184

146185
const oak = createOakContractsClient({ chain, provider, signer });
147186
```
148187

188+
:::info Unsupported chains
189+
If Privy does not include your chain in its default networks, register it in the Privy provider. See [Configuring EVM networks](https://docs.privy.io/basics/react/advanced/configuring-evm-networks) in the Privy documentation.
190+
:::
191+
149192
## Signer resolution priority
150193

151194
When a write or simulate method runs, the signer is resolved in this order:
152195

153-
1. **Per-call** `options.signer` — highest priority
154-
2. **Per-entity** `signer` passed to the entity factory (e.g. `oak.globalParams(addr, { signer })`)
155-
3. **Client-level** `walletClient` from `createOakContractsClient` (simple or full config with a wallet)
156-
4. **Throws** an `Error` from `requireSigner()` (message begins with `No signer configured.`) if none of the above is set
196+
1. **Per-call** `options.signer` — highest priority
197+
2. **Per-entity** `signer` passed to the entity factory (e.g. `oak.globalParams(addr, { signer })`)
198+
3. **Client-level** `walletClient` from `createOakContractsClient` (simple or full config with a wallet)
199+
4. **Throws** an `Error` from `requireSigner()` (message begins with `No signer configured.`) if none of the above is set
157200

158201
## Client options
159202

160-
| Option | Type | Default | Description |
161-
|---|---|---|---|
203+
| Option | Type | Default | Description |
204+
| --------- | -------- | ------- | --------------------------------------------------------------------------- |
162205
| `timeout` | `number` | `30000` | Timeout in milliseconds for transport calls and `waitForTransactionReceipt` |
163206

164207
```typescript
165208
const oak = createOakContractsClient({
166-
chainId: CHAIN_IDS.CELO_TESTNET_SEPOLIA,
167-
rpcUrl: 'https://forno.celo-sepolia.celo-testnet.org',
209+
chainId: CHAIN_IDS.CELO_TESTNET_SEPOLIA,
210+
rpcUrl: 'https://forno.celo-sepolia.celo-testnet.org',
168211
privateKey: '0x...',
169212
options: {
170213
timeout: 60000, // 60 seconds
@@ -176,12 +219,12 @@ const oak = createOakContractsClient({
176219

177220
Once created, the client exposes these read-only properties:
178221

179-
| Property | Type | Description |
180-
|---|---|---|
181-
| `config` | `PublicOakContractsClientConfig` | Public chain configuration (no secrets) |
182-
| `options` | `OakContractsClientOptions` | Resolved client options |
183-
| `publicClient` | `PublicClient` | Viem `PublicClient` for custom reads |
184-
| `walletClient` | `WalletClient \| null` | Viem `WalletClient` for custom writes (`null` for read-only clients) |
222+
| Property | Type | Description |
223+
| -------------- | -------------------------------- | -------------------------------------------------------------------- |
224+
| `config` | `PublicOakContractsClientConfig` | Public chain configuration (no secrets) |
225+
| `options` | `OakContractsClientOptions` | Resolved client options |
226+
| `publicClient` | `PublicClient` | Viem `PublicClient` for custom reads |
227+
| `walletClient` | `WalletClient \| null` | Viem `WalletClient` for custom writes (`null` for read-only clients) |
185228

186229
## Waiting for receipts
187230

@@ -199,8 +242,8 @@ console.log('Logs:', receipt.logs.length);
199242

200243
The receipt includes:
201244

202-
| Field | Type | Description |
203-
|---|---|---|
204-
| `blockNumber` | `bigint` | Block in which the transaction was mined |
205-
| `gasUsed` | `bigint` | Total gas consumed |
206-
| `logs` | `readonly { topics, data }[]` | Raw log entries from the transaction |
245+
| Field | Type | Description |
246+
| ------------- | ----------------------------- | ---------------------------------------- |
247+
| `blockNumber` | `bigint` | Block in which the transaction was mined |
248+
| `gasUsed` | `bigint` | Total gas consumed |
249+
| `logs` | `readonly { topics, data }[]` | Raw log entries from the transaction |

‎docs/contracts-sdk/error-handling.md‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ Contract calls can revert with on-chain errors. The SDK decodes raw revert data
77
Use `parseContractError()` to decode raw revert data from a failed transaction or simulation:
88

99
```typescript
10-
import { parseContractError, getRevertData } from '@oaknetwork/contracts';
10+
import { parseContractError, getRevertData } from '@oaknetwork/contracts-sdk';
1111

1212
function handleError(err) {
1313
// If the error is already a typed SDK error (thrown by simulate methods)
@@ -61,7 +61,7 @@ interface ContractErrorBase {
6161
Use `simulateWithErrorDecode()` to wrap a `simulateContract` call. It catches reverts, decodes them, and re-throws as typed SDK errors:
6262

6363
```typescript
64-
import { simulateWithErrorDecode } from '@oaknetwork/contracts';
64+
import { simulateWithErrorDecode } from '@oaknetwork/contracts-sdk';
6565

6666
try {
6767
await simulateWithErrorDecode(() =>
@@ -218,7 +218,7 @@ try {
218218
import {
219219
GlobalParamsPlatformNotListedError,
220220
CampaignInfoFactoryInvalidInputError,
221-
} from '@oaknetwork/contracts';
221+
} from '@oaknetwork/contracts-sdk';
222222

223223
try {
224224
await factory.createCampaign(params);
@@ -236,7 +236,7 @@ try {
236236
Convenience function to extract the recovery hint from any typed error:
237237

238238
```typescript
239-
import { getRecoveryHint } from '@oaknetwork/contracts';
239+
import { getRecoveryHint } from '@oaknetwork/contracts-sdk';
240240

241241
const hint = getRecoveryHint(err);
242242
if (hint) console.log('Suggestion:', hint);

‎docs/contracts-sdk/global-params.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ sidebar_label: GlobalParams
77
Protocol-wide configuration registry. Manages platform listings, fee settings, token currencies, line item types, and a general-purpose key-value registry.
88

99
```typescript
10-
import { createOakContractsClient, CHAIN_IDS } from '@oaknetwork/contracts';
10+
import { createOakContractsClient, CHAIN_IDS } from '@oaknetwork/contracts-sdk';
1111

1212
const oak = createOakContractsClient({ ... });
1313
const gp = oak.globalParams('0x...contractAddress');
@@ -72,7 +72,7 @@ console.log('Fee:', fee, 'bps'); // 100n = 1%
7272
### Enlist a platform
7373

7474
```typescript
75-
import { keccak256, toHex } from '@oaknetwork/contracts';
75+
import { keccak256, toHex } from '@oaknetwork/contracts-sdk';
7676

7777
const PLATFORM_HASH = keccak256(toHex('my-platform'));
7878

‎docs/contracts-sdk/installation.md‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
# Installation
22

3-
The `@oaknetwork/contracts` package is published on npm. Install it with your preferred package manager.
3+
The `@oaknetwork/contracts-sdk` package is published on npm. Install it with your preferred package manager.
44

55
```bash
6-
pnpm add @oaknetwork/contracts
6+
pnpm add @oaknetwork/contracts-sdk
77
```
88

9-
> You can also use `npm install @oaknetwork/contracts` or `yarn add @oaknetwork/contracts`.
9+
> You can also use `npm install @oaknetwork/contracts-sdk` or `yarn add @oaknetwork/contracts-sdk`.
1010
1111
## Requirements
1212

13-
- `@oaknetwork/contracts` **>= 1.0.0**
13+
- `@oaknetwork/contracts-sdk` **>= 1.0.0**
1414
- Node.js 18 or later
1515
- TypeScript 5.x recommended (the SDK ships type declarations)
1616

@@ -21,7 +21,7 @@ The SDK depends on [viem](https://viem.sh) for blockchain interactions. It is in
2121
The SDK ships a `CHAIN_IDS` constant with all supported networks:
2222

2323
```typescript
24-
import { CHAIN_IDS } from '@oaknetwork/contracts';
24+
import { CHAIN_IDS } from '@oaknetwork/contracts-sdk';
2525

2626
CHAIN_IDS.ETHEREUM_MAINNET; // 1
2727
CHAIN_IDS.CELO_MAINNET; // 42220

‎docs/contracts-sdk/item-registry.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ interface Item {
4545
### Register an item
4646

4747
```typescript
48-
import { keccak256, toHex } from '@oaknetwork/contracts';
48+
import { keccak256, toHex } from '@oaknetwork/contracts-sdk';
4949

5050
const itemId = keccak256(toHex('premium-t-shirt'));
5151

‎docs/contracts-sdk/keep-whats-raised.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ interface KeepWhatsRaisedFeeValues {
126126
### Configure the treasury
127127

128128
```typescript
129-
import { toHex, getCurrentTimestamp, addDays } from '@oaknetwork/contracts';
129+
import { toHex, getCurrentTimestamp, addDays } from '@oaknetwork/contracts-sdk';
130130

131131
const now = getCurrentTimestamp();
132132

@@ -161,7 +161,7 @@ await oak.waitForReceipt(txHash);
161161
### Pledge with a reward
162162

163163
```typescript
164-
import { keccak256, toHex } from '@oaknetwork/contracts';
164+
import { keccak256, toHex } from '@oaknetwork/contracts-sdk';
165165

166166
const pledgeId = keccak256(toHex('pledge-001'));
167167
const rewardName = keccak256(toHex('gold-tier'));

0 commit comments

Comments
 (0)