@sodax/wallet-sdk-core 1.5.7-beta → 2.0.0-rc.2
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 +231 -1
- package/ai-exported/AGENTS.md +139 -0
- package/ai-exported/integration/README.md +108 -0
- package/ai-exported/integration/ai-rules.md +141 -0
- package/ai-exported/integration/architecture.md +212 -0
- package/ai-exported/integration/features/README.md +22 -0
- package/ai-exported/integration/features/bitcoin.md +103 -0
- package/ai-exported/integration/features/evm.md +102 -0
- package/ai-exported/integration/features/icon.md +88 -0
- package/ai-exported/integration/features/injective.md +92 -0
- package/ai-exported/integration/features/near.md +92 -0
- package/ai-exported/integration/features/solana.md +104 -0
- package/ai-exported/integration/features/stacks.md +91 -0
- package/ai-exported/integration/features/stellar.md +95 -0
- package/ai-exported/integration/features/sui.md +96 -0
- package/ai-exported/integration/quickstart.md +259 -0
- package/ai-exported/integration/recipes/README.md +15 -0
- package/ai-exported/integration/recipes/bridge-to-sdk.md +145 -0
- package/ai-exported/integration/recipes/defaults-and-overrides.md +159 -0
- package/ai-exported/integration/recipes/library-exports.md +129 -0
- package/ai-exported/integration/recipes/setup-browser-extension.md +137 -0
- package/ai-exported/integration/recipes/setup-private-key.md +115 -0
- package/ai-exported/integration/recipes/sign-and-broadcast.md +201 -0
- package/ai-exported/integration/recipes/testing.md +163 -0
- package/ai-exported/integration/reference/README.md +13 -0
- package/ai-exported/integration/reference/chain-support.md +65 -0
- package/ai-exported/integration/reference/glossary.md +28 -0
- package/ai-exported/integration/reference/interfaces.md +131 -0
- package/ai-exported/integration/reference/provider-classes.md +54 -0
- package/ai-exported/integration/reference/public-api.md +128 -0
- package/ai-exported/migration/README.md +84 -0
- package/ai-exported/migration/ai-rules.md +139 -0
- package/ai-exported/migration/breaking-changes/README.md +14 -0
- package/ai-exported/migration/breaking-changes/base-wallet-provider.md +52 -0
- package/ai-exported/migration/breaking-changes/defaults-config.md +57 -0
- package/ai-exported/migration/breaking-changes/folder-layout.md +99 -0
- package/ai-exported/migration/breaking-changes/library-exports.md +58 -0
- package/ai-exported/migration/checklist.md +62 -0
- package/ai-exported/migration/recipes/README.md +12 -0
- package/ai-exported/migration/recipes/adopt-defaults.md +84 -0
- package/ai-exported/migration/recipes/adopt-library-exports.md +99 -0
- package/ai-exported/migration/reference/README.md +12 -0
- package/ai-exported/migration/reference/added-fields.md +71 -0
- package/ai-exported/migration/reference/deleted-exports.md +35 -0
- package/ai-exported/migration/reference/renamed-symbols.md +31 -0
- package/ai-exported/migration/reference/return-shapes.md +23 -0
- package/dist/index.cjs +3200 -2392
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +415 -128
- package/dist/index.d.ts +415 -128
- package/dist/index.mjs +3197 -2395
- package/dist/index.mjs.map +1 -1
- package/package.json +10 -8
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
# Recipe: `library-exports` — re-import upstream chain types
|
|
2
|
+
|
|
3
|
+
Avoid adding `viem`, `@mysten/sui`, `@solana/web3.js`, etc. as direct `package.json` deps. `@sodax/wallet-sdk-core` re-exports a curated set of types (and a handful of runtime enums) from each upstream chain SDK.
|
|
4
|
+
|
|
5
|
+
**Depends on:** none — pure type-level optimisation.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## What's re-exported
|
|
10
|
+
|
|
11
|
+
Source file: `src/types/library-exports.ts`. The export name is the same as upstream — only the source module changes.
|
|
12
|
+
|
|
13
|
+
### Types (no runtime cost)
|
|
14
|
+
|
|
15
|
+
| Chain SDK | Re-exported types |
|
|
16
|
+
|---|---|
|
|
17
|
+
| `viem` | `Account`, `Address`, `Chain`, `Transport`, `PublicClient`, `WalletClient`, `HttpTransportConfig`, `PublicClientConfig`, `WalletClientConfig`, `SendTransactionParameters`, `WaitForTransactionReceiptParameters`, `TransactionReceipt` |
|
|
18
|
+
| `@mysten/sui/client` | `SuiTransactionBlockResponseOptions` |
|
|
19
|
+
| `@mysten/sui/transactions` | `Transaction`, `TransactionArgument` |
|
|
20
|
+
| `@mysten/wallet-standard` | `SuiWalletFeatures`, `WalletAccount`, `WalletWithFeatures` |
|
|
21
|
+
| `@solana/web3.js` | `Commitment`, `ConnectionConfig`, `SendOptions` |
|
|
22
|
+
| `@injectivelabs/networks` | `Network` |
|
|
23
|
+
| `@injectivelabs/ts-types` | `ChainId`, `EvmChainId` |
|
|
24
|
+
| `@injectivelabs/wallet-core` | `MsgBroadcaster` |
|
|
25
|
+
| `@stacks/transactions` | `ClarityValue`, `PostConditionModeName` |
|
|
26
|
+
| `@stacks/network` | `StacksNetwork` |
|
|
27
|
+
| `@stacks/connect` | `StacksProvider` |
|
|
28
|
+
| `near-api-js` | `KeyPairString` |
|
|
29
|
+
| `@hot-labs/near-connect` | `NearConnector` |
|
|
30
|
+
| `bitcoinjs-lib/src/networks.js` | `Network as BitcoinJsNetwork` |
|
|
31
|
+
|
|
32
|
+
### Runtime values (also re-exported)
|
|
33
|
+
|
|
34
|
+
| Source | Value | Why include the runtime |
|
|
35
|
+
|---|---|---|
|
|
36
|
+
| `@stellar/stellar-sdk` | `Networks` (object) | Consumers commonly read `Networks.PUBLIC` / `Networks.TESTNET` |
|
|
37
|
+
| `@stacks/transactions` | `PostConditionMode` (enum) | Used as a value when building Stacks tx params |
|
|
38
|
+
|
|
39
|
+
Note the file name: `library-exports` (not `library-types`). It exists precisely because the file mixes type and runtime re-exports.
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## Usage
|
|
44
|
+
|
|
45
|
+
```ts
|
|
46
|
+
// ✅ DO — types and the two runtime enums via wallet-sdk-core
|
|
47
|
+
import type {
|
|
48
|
+
WalletClient,
|
|
49
|
+
PublicClient,
|
|
50
|
+
TransactionReceipt,
|
|
51
|
+
SuiWalletFeatures,
|
|
52
|
+
WalletAccount,
|
|
53
|
+
WalletWithFeatures,
|
|
54
|
+
ConnectionConfig,
|
|
55
|
+
Network,
|
|
56
|
+
ChainId,
|
|
57
|
+
StacksNetwork,
|
|
58
|
+
StacksProvider,
|
|
59
|
+
NearConnector,
|
|
60
|
+
} from '@sodax/wallet-sdk-core';
|
|
61
|
+
|
|
62
|
+
import { Networks, PostConditionMode } from '@sodax/wallet-sdk-core';
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
```ts
|
|
66
|
+
// ❌ DON'T — direct upstream imports for these names if you only need them as types
|
|
67
|
+
import type { WalletClient } from 'viem';
|
|
68
|
+
import { Networks } from '@stellar/stellar-sdk';
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## When to NOT use re-exports
|
|
74
|
+
|
|
75
|
+
The re-export list is **curated** — only the types most consumers need. Use the upstream package directly when:
|
|
76
|
+
|
|
77
|
+
- You need a type not in the re-export list (e.g. viem's `TransactionRequest`, Solana's `Keypair` value).
|
|
78
|
+
- You need a **runtime value** other than `Networks` / `PostConditionMode` (e.g. viem's `createPublicClient`, `@solana/web3.js`'s `Connection`).
|
|
79
|
+
- You are building a polyfill, mock, or shim around the underlying SDK.
|
|
80
|
+
|
|
81
|
+
In those cases, add the upstream package to `package.json` and import normally. The re-export is an optimisation, not a hard wall.
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## Why `library-exports` exists
|
|
86
|
+
|
|
87
|
+
| Without it | With it |
|
|
88
|
+
|---|---|
|
|
89
|
+
| Consumer `package.json` lists 8+ chain SDKs explicitly | Consumer lists only `@sodax/wallet-sdk-core` + `@sodax/types` |
|
|
90
|
+
| Upgrading a chain SDK touches consumer lockfiles | SODAX bumps the SDK; consumers re-install |
|
|
91
|
+
| Type drift between SODAX and consumer (different `viem` minor versions) | Single source of truth — same `viem` version as SODAX uses internally |
|
|
92
|
+
|
|
93
|
+
The trade-off is the curated list — uncommon types need a direct dep.
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
## Verification
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
# 1. Type check
|
|
101
|
+
pnpm checkTs
|
|
102
|
+
|
|
103
|
+
# 2. Confirm no direct upstream imports for re-exported types
|
|
104
|
+
grep -rn "from 'viem'" <user-src> | grep -E "WalletClient|PublicClient|TransactionReceipt|SendTransactionParameters"
|
|
105
|
+
grep -rn "from '@stellar/stellar-sdk'" <user-src> | grep "Networks"
|
|
106
|
+
grep -rn "from '@stacks/transactions'" <user-src> | grep "PostConditionMode"
|
|
107
|
+
# expect empty for all three
|
|
108
|
+
|
|
109
|
+
# 3. Confirm the chain SDKs are NOT direct deps in consumer's package.json
|
|
110
|
+
cat <user>/package.json | grep -E '"viem"|"@stellar/stellar-sdk"|"@stacks/transactions"|"@mysten/sui"|"@solana/web3.js"|"@injectivelabs"|"near-api-js"|"bitcoinjs-lib"'
|
|
111
|
+
# expect empty unless the consumer legitimately uses a non-re-exported symbol
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
---
|
|
115
|
+
|
|
116
|
+
## Common pitfalls
|
|
117
|
+
|
|
118
|
+
| Pitfall | Symptom | Fix |
|
|
119
|
+
|---|---|---|
|
|
120
|
+
| Importing `Networks` from `@stellar/stellar-sdk` after install | Works, but adds a direct dep | Switch to `import { Networks } from '@sodax/wallet-sdk-core'` |
|
|
121
|
+
| Mixing type-only and value imports in one statement | Build size grows | `import type { … }` for types; separate value imports |
|
|
122
|
+
| Expecting all viem helpers to be re-exported | `createPublicClient` is missing | Only types + 2 enums are re-exported. Other runtime helpers require direct install. |
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
## See also
|
|
127
|
+
|
|
128
|
+
- [`../architecture.md`](../architecture.md) § `library-exports` — the upstream-SDK indirection.
|
|
129
|
+
- [`../reference/public-api.md`](../reference/public-api.md) — full barrel export list.
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
# Recipe: Setup — browser-extension mode
|
|
2
|
+
|
|
3
|
+
Construct a `*WalletProvider` from a wallet adapter that the user has already connected (MetaMask via wagmi, Phantom via wallet-adapter, Xverse via a kit, …).
|
|
4
|
+
|
|
5
|
+
**Depends on:** the consumer app already obtains a chain-specific signer / client from the extension. Inside a React app, prefer `useWalletProvider` from `@sodax/wallet-sdk-react` — see § "When to skip this recipe" below.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Pick the right chain
|
|
10
|
+
|
|
11
|
+
Each chain has its own browser-extension variant. See [`../features/<chain>.md`](../features/) for exact field shapes.
|
|
12
|
+
|
|
13
|
+
| Chain | Required inputs |
|
|
14
|
+
|---|---|
|
|
15
|
+
| EVM | `walletClient` (viem `WalletClient<Transport, Chain, Account>`) + `publicClient` (viem `PublicClient`) |
|
|
16
|
+
| Solana | `wallet: { publicKey, signTransaction }` + `endpoint` |
|
|
17
|
+
| Sui | `client` (`SuiClient`) + `wallet` (`WalletWithFeatures<Partial<SuiWalletFeatures>>`) + `account` (`WalletAccount`) |
|
|
18
|
+
| Bitcoin | `type: 'BROWSER_EXTENSION'`, `walletsKit` (consumer-supplied adapter), `network` |
|
|
19
|
+
| Stellar | `type: 'BROWSER_EXTENSION'`, `walletsKit`, `network` |
|
|
20
|
+
| ICON | `walletAddress` (optional `hx…`) + `rpcUrl` |
|
|
21
|
+
| Injective | `msgBroadcaster` |
|
|
22
|
+
| NEAR | `wallet` (`NearConnector` from `@hot-labs/near-connect`) |
|
|
23
|
+
| Stacks | `address` + optional `provider` (StacksProvider) |
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Pattern: EVM (with wagmi clients)
|
|
28
|
+
|
|
29
|
+
```ts
|
|
30
|
+
import { EvmWalletProvider } from '@sodax/wallet-sdk-core';
|
|
31
|
+
import type { WalletClient, PublicClient } from '@sodax/wallet-sdk-core';
|
|
32
|
+
import { useWalletClient, usePublicClient } from 'wagmi';
|
|
33
|
+
// …or wherever your app sources the viem clients
|
|
34
|
+
|
|
35
|
+
function buildProvider(walletClient: WalletClient, publicClient: PublicClient) {
|
|
36
|
+
return new EvmWalletProvider({
|
|
37
|
+
walletClient,
|
|
38
|
+
publicClient,
|
|
39
|
+
// Optional — `defaults.sendTransaction` and `defaults.waitForTransactionReceipt`
|
|
40
|
+
// are honored. `defaults.transport / publicClient / walletClient` are IGNORED
|
|
41
|
+
// in browser-extension mode (the provider logs a one-time warning).
|
|
42
|
+
defaults: {
|
|
43
|
+
sendTransaction: { gas: 1_000_000n },
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## Pattern: Solana (with `@solana/wallet-adapter-react`)
|
|
52
|
+
|
|
53
|
+
```ts
|
|
54
|
+
import { SolanaWalletProvider } from '@sodax/wallet-sdk-core';
|
|
55
|
+
import { useWallet } from '@solana/wallet-adapter-react';
|
|
56
|
+
|
|
57
|
+
function buildProvider() {
|
|
58
|
+
const { publicKey, signTransaction } = useWallet();
|
|
59
|
+
return new SolanaWalletProvider({
|
|
60
|
+
wallet: { publicKey, signTransaction }, // both may be null/undefined until connected
|
|
61
|
+
endpoint: 'https://api.mainnet-beta.solana.com',
|
|
62
|
+
defaults: { sendOptions: { skipPreflight: false } },
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## Pattern: Bitcoin / Stellar (explicit `type`)
|
|
70
|
+
|
|
71
|
+
```ts
|
|
72
|
+
import { BitcoinWalletProvider } from '@sodax/wallet-sdk-core';
|
|
73
|
+
|
|
74
|
+
const provider = new BitcoinWalletProvider({
|
|
75
|
+
type: 'BROWSER_EXTENSION',
|
|
76
|
+
walletsKit: myBitcoinAdapter, // implements BitcoinWalletsKit
|
|
77
|
+
network: 'MAINNET',
|
|
78
|
+
});
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
The `walletsKit` is a consumer-provided adapter (Xverse / Unisat / OKX) that conforms to the `BitcoinWalletsKit` interface — see [`../features/bitcoin.md`](../features/bitcoin.md).
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## When to skip this recipe
|
|
86
|
+
|
|
87
|
+
You almost never construct browser-extension providers **manually** inside a React component. The right path is:
|
|
88
|
+
|
|
89
|
+
```tsx
|
|
90
|
+
import { useWalletProvider } from '@sodax/wallet-sdk-react';
|
|
91
|
+
import { ChainKeys } from '@sodax/types';
|
|
92
|
+
|
|
93
|
+
const evm = useWalletProvider({ xChainId: ChainKeys.SONIC_MAINNET });
|
|
94
|
+
// evm: IEvmWalletProvider | undefined ← already typed, already wired
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
`@sodax/wallet-sdk-react` handles the construction internally — see its `ai-exported/integration/recipes/setup.md`. Skip this recipe (the manual path) unless you are:
|
|
98
|
+
|
|
99
|
+
- Building a custom non-React frontend that talks to a wallet extension directly.
|
|
100
|
+
- Writing a thin wrapper around the package for a framework that doesn't have a SODAX integration yet.
|
|
101
|
+
- Migrating a legacy non-React app.
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
## Verification
|
|
106
|
+
|
|
107
|
+
```ts
|
|
108
|
+
console.log(await provider.getWalletAddress()); // smoke test
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
# Type check
|
|
113
|
+
pnpm checkTs
|
|
114
|
+
|
|
115
|
+
# Confirm no deep imports
|
|
116
|
+
grep -rn "@sodax/wallet-sdk-core/" <user-src> | grep -v "from '@sodax/wallet-sdk-core'"
|
|
117
|
+
# expect empty
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## Common errors
|
|
123
|
+
|
|
124
|
+
| Error | Cause | Fix |
|
|
125
|
+
|---|---|---|
|
|
126
|
+
| `signTransaction is not a function` (Solana) | Wallet adapter didn't provide a signer for the connected wallet | Gate construction on `signTransaction != null`. |
|
|
127
|
+
| `WalletAccount is undefined` (Sui) | Adapter exposes `wallet` but not the active `account` | Read `wallet.accounts[0]` or your adapter's "current account" API before constructing. |
|
|
128
|
+
| `[EvmWalletProvider] defaults.{transport,publicClient,walletClient} ignored…` | Mixed PK-mode defaults with browser-extension config | Move those defaults out — they only apply in private-key mode. |
|
|
129
|
+
| Mode picked the wrong variant (TypeScript narrowing fails) | Mixed PK and browser fields | Pick **one** discriminated union variant. Don't pass both. |
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
## Next steps
|
|
134
|
+
|
|
135
|
+
- [`bridge-to-sdk.md`](./bridge-to-sdk.md) — hand off the provider to `@sodax/sdk` calls.
|
|
136
|
+
- [`library-exports.md`](./library-exports.md) — avoid taking `viem` / `@mysten/sui` / etc. as direct deps when importing types.
|
|
137
|
+
- [`defaults-and-overrides.md`](./defaults-and-overrides.md) — tune `defaults`.
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# Recipe: Setup — private-key mode
|
|
2
|
+
|
|
3
|
+
Construct a `*WalletProvider` from a raw key. Use this in Node scripts, CI, tests, indexers, bots — anywhere the runtime legitimately possesses a secret.
|
|
4
|
+
|
|
5
|
+
**Depends on:** none. **Do NOT** use this in a browser bundle.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Pick the right chain
|
|
10
|
+
|
|
11
|
+
Each chain has its own discriminated union. See [`../features/<chain>.md`](../features/) for exact field names.
|
|
12
|
+
|
|
13
|
+
| Chain | Field that triggers PK mode | Credential shape |
|
|
14
|
+
|---|---|---|
|
|
15
|
+
| EVM | `privateKey: '0x…'` | hex string |
|
|
16
|
+
| Solana | `privateKey: Uint8Array` | 64-byte secret key |
|
|
17
|
+
| Sui | `mnemonics: '…'` | BIP-39 phrase (no raw key option) |
|
|
18
|
+
| Bitcoin | `type: 'PRIVATE_KEY'`, `privateKey: '0x…'`| hex string + uppercase `type` |
|
|
19
|
+
| Stellar | `type: 'PRIVATE_KEY'`, `privateKey: '0x…'`| hex string + uppercase `type` |
|
|
20
|
+
| ICON | `privateKey: '0x…'` | hex string |
|
|
21
|
+
| Injective | `secret: { privateKey } \| { mnemonics }` | nested credential object |
|
|
22
|
+
| NEAR | `privateKey: 'ed25519:…'`, `accountId` | algorithm-prefixed string + accountId |
|
|
23
|
+
| Stacks | `privateKey: '…'` | string |
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Install
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
pnpm add @sodax/wallet-sdk-core @sodax/types
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
If you'll hand off to `@sodax/sdk`, add it too:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
pnpm add @sodax/sdk
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## Pattern: EVM (representative)
|
|
42
|
+
|
|
43
|
+
```ts
|
|
44
|
+
import 'dotenv/config';
|
|
45
|
+
import { EvmWalletProvider } from '@sodax/wallet-sdk-core';
|
|
46
|
+
import { ChainKeys } from '@sodax/types';
|
|
47
|
+
|
|
48
|
+
const PRIVATE_KEY = process.env.EVM_PRIVATE_KEY as `0x${string}`;
|
|
49
|
+
if (!PRIVATE_KEY) throw new Error('EVM_PRIVATE_KEY is required');
|
|
50
|
+
|
|
51
|
+
const provider = new EvmWalletProvider({
|
|
52
|
+
privateKey: PRIVATE_KEY,
|
|
53
|
+
chainId: ChainKeys.SONIC_MAINNET, // pick any EvmChainKey
|
|
54
|
+
rpcUrl: process.env.EVM_RPC_URL, // optional — defaults to viem chain's public RPC
|
|
55
|
+
defaults: {
|
|
56
|
+
sendTransaction: { gas: 3_000_000n }, // env-level fixed default
|
|
57
|
+
},
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
const address = await provider.getWalletAddress();
|
|
61
|
+
console.log('Signing as:', address);
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
For other chains, swap the import and follow the field table above. Full snippets per chain live in [`../quickstart.md`](../quickstart.md).
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## Keep the secret out of code
|
|
69
|
+
|
|
70
|
+
| Anti-pattern | Why bad | Replacement |
|
|
71
|
+
|---|---|---|
|
|
72
|
+
| `privateKey: '0xabc…'` inline | Key in version control | `process.env.EVM_PRIVATE_KEY` |
|
|
73
|
+
| `.env` committed to git | Same as above | `.env` in `.gitignore`, only `.env.example` committed |
|
|
74
|
+
| Key in a frontend bundle | Browser users can read it | Use `setup-browser-extension.md` |
|
|
75
|
+
| Key passed via CLI argv | Shows up in shell history | `dotenv-cli` + `.env` file |
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## Verification
|
|
80
|
+
|
|
81
|
+
```ts
|
|
82
|
+
// Get-address smoke test
|
|
83
|
+
console.log(await provider.getWalletAddress());
|
|
84
|
+
|
|
85
|
+
// Optional: dry-run a balance read
|
|
86
|
+
// (chain-specific — see ../features/<chain>.md)
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
# 1. Type check passes
|
|
91
|
+
pnpm checkTs
|
|
92
|
+
|
|
93
|
+
# 2. Confirm only one provider import — barrel only
|
|
94
|
+
grep -rn "from '@sodax/wallet-sdk-core" <script-dir>
|
|
95
|
+
# expect zero deep paths like @sodax/wallet-sdk-core/src/...
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
## Common errors
|
|
101
|
+
|
|
102
|
+
| Error | Cause | Fix |
|
|
103
|
+
|---|---|---|
|
|
104
|
+
| `Invalid EVM wallet config` | Mixed PK and browser-extension fields in one object | Pick **one** variant. Don't pass both `privateKey` and `walletClient`. |
|
|
105
|
+
| TS2322: `'string'` is not assignable to `` `0x${string}` `` | Missing hex prefix or wrong type | Read from env with `as \`0x${string}\`` after a runtime check. |
|
|
106
|
+
| TS: `Property 'secret' is missing` (Injective) | Used `privateKey` at top level | Wrap in `{ secret: { privateKey } }` or `{ secret: { mnemonics } }`. See [`../features/injective.md`](../features/injective.md). |
|
|
107
|
+
| `Cannot find module 'viem/chains'` for unknown chain | Passed an EVM chain key not in `getEvmViemChain` | Use a `ChainKeys.*_MAINNET` constant — the function is exhaustive. |
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
## Next steps
|
|
112
|
+
|
|
113
|
+
- [`bridge-to-sdk.md`](./bridge-to-sdk.md) — pass the provider to `@sodax/sdk` for swap / lend / bridge / stake.
|
|
114
|
+
- [`defaults-and-overrides.md`](./defaults-and-overrides.md) — tune the `defaults` slice.
|
|
115
|
+
- [`sign-and-broadcast.md`](./sign-and-broadcast.md) — chain-by-chain raw-tx flow.
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
# Recipe: Sign and broadcast (per chain)
|
|
2
|
+
|
|
3
|
+
Minimal raw-tx flows for each chain. Use these as smoke tests after construction, or when integrating outside of `@sodax/sdk`.
|
|
4
|
+
|
|
5
|
+
**Depends on:** [`setup-private-key.md`](./setup-private-key.md) or [`setup-browser-extension.md`](./setup-browser-extension.md).
|
|
6
|
+
|
|
7
|
+
For SDK-mediated flows (deposit, swap, bridge, lend, stake) see [`bridge-to-sdk.md`](./bridge-to-sdk.md) instead — this recipe is for chain-native raw transactions.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## EVM
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
import type { EvmRawTransaction } from '@sodax/types';
|
|
15
|
+
|
|
16
|
+
const tx: EvmRawTransaction = {
|
|
17
|
+
to: '0x…',
|
|
18
|
+
value: 1_000_000_000_000_000n, // 0.001 ETH
|
|
19
|
+
data: '0x',
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const hash = await provider.sendTransaction(tx);
|
|
23
|
+
// Optional per-call override: { gas: 5_000_000n }
|
|
24
|
+
|
|
25
|
+
const receipt = await provider.waitForTransactionReceipt(hash);
|
|
26
|
+
// Receipt is bigint-stringified — JSON-safe. receipt.blockNumber: string.
|
|
27
|
+
console.log(receipt.status, receipt.blockNumber);
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## Solana
|
|
33
|
+
|
|
34
|
+
```ts
|
|
35
|
+
import type { SolanaRawTransactionInstruction } from '@sodax/types';
|
|
36
|
+
|
|
37
|
+
const instructions: SolanaRawTransactionInstruction[] = [/* … */];
|
|
38
|
+
|
|
39
|
+
const rawTx = await provider.buildV0Txn(instructions);
|
|
40
|
+
const signature = await provider.sendTransactionWithConfirmation(rawTx);
|
|
41
|
+
|
|
42
|
+
console.log('signature:', signature);
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
`buildV0Txn` picks the keypair-vs-adapter signing path internally. `sendTransactionWithConfirmation` waits to the `defaults.confirmCommitment` level (default `'finalized'`).
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## Sui
|
|
50
|
+
|
|
51
|
+
```ts
|
|
52
|
+
import type { SuiTransaction } from '@sodax/types';
|
|
53
|
+
|
|
54
|
+
const tx: SuiTransaction = /* build with @mysten/sui Transaction builder */;
|
|
55
|
+
|
|
56
|
+
const digest = await provider.signAndExecuteTxn(tx);
|
|
57
|
+
// Pre-flight dry-run is on by default. Disable for a doomed-tx flow:
|
|
58
|
+
// await provider.signAndExecuteTxn(tx, { dryRun: { enabled: false } });
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## Bitcoin
|
|
64
|
+
|
|
65
|
+
```ts
|
|
66
|
+
// 1. Build a PSBT externally (or via your wallet kit) and serialise to base64.
|
|
67
|
+
const psbtBase64 = '/* … */';
|
|
68
|
+
|
|
69
|
+
// 2. Sign (finalize defaults to defaults.defaultFinalize, default true).
|
|
70
|
+
const signedTxOrPsbt = await provider.signTransaction(psbtBase64);
|
|
71
|
+
|
|
72
|
+
// 3. Broadcast — either via the wallet kit (browser mode) or your own broadcaster.
|
|
73
|
+
// PK mode does not implement a broadcaster in this provider — you submit the
|
|
74
|
+
// finalised tx to your own node or a public API.
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
For message signing:
|
|
78
|
+
|
|
79
|
+
```ts
|
|
80
|
+
const sig = await provider.signEcdsaMessage('hello');
|
|
81
|
+
const sig322 = await provider.signBip322Message('hello');
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## Stellar
|
|
87
|
+
|
|
88
|
+
```ts
|
|
89
|
+
import type { XDR } from '@sodax/types';
|
|
90
|
+
|
|
91
|
+
// 1. Build the XDR externally (TransactionBuilder from @stellar/stellar-sdk).
|
|
92
|
+
const txXdr: XDR = '/* … */';
|
|
93
|
+
|
|
94
|
+
// 2. Sign.
|
|
95
|
+
const signedXdr = await provider.signTransaction(txXdr);
|
|
96
|
+
|
|
97
|
+
// 3. Submit to Horizon (the provider's `server` is private; build a Horizon.Server
|
|
98
|
+
// yourself or use a service layer that wraps submit).
|
|
99
|
+
|
|
100
|
+
// 4. Wait for inclusion (polls Horizon).
|
|
101
|
+
const receipt = await provider.waitForTransactionReceipt(submittedHash);
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
## ICON
|
|
107
|
+
|
|
108
|
+
```ts
|
|
109
|
+
import type { IcxCallTransaction } from '@sodax/types';
|
|
110
|
+
|
|
111
|
+
const tx: IcxCallTransaction = /* build with icon-sdk-js IcxTransactionBuilder */;
|
|
112
|
+
|
|
113
|
+
const hash = await provider.sendTransaction(tx);
|
|
114
|
+
// Override step limit / version per call: { stepLimit: 5_000_000 }
|
|
115
|
+
|
|
116
|
+
const result = await provider.waitForTransactionReceipt(hash);
|
|
117
|
+
console.log(result.status);
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## Injective
|
|
123
|
+
|
|
124
|
+
```ts
|
|
125
|
+
// Reads the address (and pubkey) from the configured secret / msgBroadcaster.
|
|
126
|
+
const address = await provider.getWalletAddress();
|
|
127
|
+
const pubKey = await provider.getWalletPubKey();
|
|
128
|
+
|
|
129
|
+
// Build + execute via the upstream MsgBroadcaster. See @injectivelabs/sdk-ts
|
|
130
|
+
// docs for the canonical message builders (MsgSend, MsgExecuteContract, …).
|
|
131
|
+
const txResp = await provider.execute(/* params per @sodax/types */);
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
For inspection-only flows, `getRawTransaction(…)` returns the unsigned tx without broadcasting.
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
## NEAR
|
|
139
|
+
|
|
140
|
+
```ts
|
|
141
|
+
import type { CallContractParams, NearRawTransaction } from '@sodax/types';
|
|
142
|
+
|
|
143
|
+
const params: CallContractParams = /* … */;
|
|
144
|
+
const tx: NearRawTransaction = await provider.getRawTransaction(params);
|
|
145
|
+
|
|
146
|
+
const hash = await provider.signAndSubmitTxn(tx);
|
|
147
|
+
// Override waitUntil per call: { waitUntil: 'EXECUTED' }
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
## Stacks
|
|
153
|
+
|
|
154
|
+
```ts
|
|
155
|
+
import type { StacksTransactionParams } from '@sodax/types';
|
|
156
|
+
import { PostConditionMode } from '@sodax/wallet-sdk-core';
|
|
157
|
+
|
|
158
|
+
const params: StacksTransactionParams = {
|
|
159
|
+
postConditionMode: PostConditionMode.Deny,
|
|
160
|
+
/* … */
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
const txResp = await provider.sendTransaction(params);
|
|
164
|
+
|
|
165
|
+
// Read-only call (no broadcast):
|
|
166
|
+
const clarityValue = await provider.readContract(params);
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
---
|
|
170
|
+
|
|
171
|
+
## Verification (any chain)
|
|
172
|
+
|
|
173
|
+
```bash
|
|
174
|
+
pnpm checkTs
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
```ts
|
|
178
|
+
// Smoke test: address read
|
|
179
|
+
console.log(await provider.getWalletAddress());
|
|
180
|
+
|
|
181
|
+
// Then attempt a tiny tx on testnet. Save the returned hash and inspect it
|
|
182
|
+
// in the chain's explorer.
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
---
|
|
186
|
+
|
|
187
|
+
## Patterns to avoid
|
|
188
|
+
|
|
189
|
+
| Anti-pattern | Why bad | Replacement |
|
|
190
|
+
|---|---|---|
|
|
191
|
+
| Constructing the `Connection` / `SuiClient` / `Horizon.Server` yourself in PK mode | Duplicates work the provider already does | Read it off the provider (`provider.connection`, etc.) when exposed; otherwise just call the method. |
|
|
192
|
+
| Storing the signed tx in localStorage / IndexedDB | Persists secrets in browser storage | Sign + broadcast in one flow; don't persist signed-but-unbroadcast txs. |
|
|
193
|
+
| Catching every error generically and logging "tx failed" | Hides real causes (nonce, insufficient gas, malformed XDR, …) | Surface the upstream error; the provider doesn't wrap them. |
|
|
194
|
+
|
|
195
|
+
---
|
|
196
|
+
|
|
197
|
+
## See also
|
|
198
|
+
|
|
199
|
+
- [`bridge-to-sdk.md`](./bridge-to-sdk.md) — handing off to `@sodax/sdk` for SODAX hub/spoke flows.
|
|
200
|
+
- [`defaults-and-overrides.md`](./defaults-and-overrides.md) — tuning the defaults slice.
|
|
201
|
+
- [`../features/<chain>.md`](../features/) — chain-specific method signatures and quirks.
|