@shelby-protocol/solana-kit 0.1.2-alpha.8 → 0.2.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 +49 -153
- package/dist/node/index.cjs +2 -2
- package/dist/node/index.d.cts +1 -1
- package/dist/node/index.d.ts +1 -1
- package/dist/node/index.mjs +3 -3
- package/dist/react/index.d.ts +1 -1
- package/dist/react/index.mjs +19 -12
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -11,209 +11,105 @@ The Solana Kit SDK was built to facilitate the development of Solana application
|
|
|
11
11
|
Install with your favorite package manager such as npm, yarn, or pnpm:
|
|
12
12
|
|
|
13
13
|
```bash
|
|
14
|
-
# Install the package
|
|
15
14
|
pnpm install @shelby-protocol/solana-kit
|
|
16
|
-
|
|
17
|
-
# For React applications (optional)
|
|
18
|
-
pnpm install react react-dom
|
|
19
15
|
```
|
|
20
16
|
|
|
21
|
-
##
|
|
17
|
+
## Entry Points
|
|
22
18
|
|
|
23
|
-
|
|
19
|
+
The package provides two entry points for different use cases:
|
|
24
20
|
|
|
25
|
-
|
|
21
|
+
| Entry Point | Import Path | Use Case |
|
|
22
|
+
|-------------|-------------|----------|
|
|
23
|
+
| **Node.js** | `@shelby-protocol/solana-kit/node` | Server-side applications, scripts, CLIs |
|
|
24
|
+
| **React** | `@shelby-protocol/solana-kit/react` | Browser applications with wallet connections |
|
|
26
25
|
|
|
27
|
-
##
|
|
26
|
+
## Quick Start
|
|
28
27
|
|
|
29
|
-
|
|
28
|
+
### Node.js / Server-side
|
|
30
29
|
|
|
31
30
|
```ts
|
|
32
31
|
import { Shelby, Network } from "@shelby-protocol/solana-kit/node";
|
|
33
|
-
import { Connection } from "@solana/web3.js";
|
|
34
|
-
|
|
35
|
-
// Create a Solana network connection
|
|
36
|
-
const connection = new Connection("https://api.devnet.solana.com");
|
|
32
|
+
import { Connection, Keypair } from "@solana/web3.js";
|
|
37
33
|
|
|
38
|
-
// Create a shelby client
|
|
39
34
|
const shelbyClient = new Shelby({
|
|
40
|
-
// The Shelby network to connect with
|
|
41
35
|
network: Network.SHELBYNET,
|
|
42
|
-
connection,
|
|
43
|
-
// The Shelby API Key
|
|
36
|
+
connection: new Connection("https://api.devnet.solana.com"),
|
|
44
37
|
apiKey: "AG-***",
|
|
45
38
|
});
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
## Shelby Storage Account
|
|
49
|
-
|
|
50
|
-
Shelby uses the Aptos blockchain as a coordination and settlement layer. Aptos provides a high-performance, reliable foundation for managing system state and economic logic. As a result, uploading blobs to the Shelby Protocol requires communication with the Aptos network.
|
|
51
|
-
|
|
52
|
-
To allow a Solana identity to own data in Shelby, the protocol leverages [Aptos Derivable Account Abstraction](https://github.com/aptos-foundation/AIPs/blob/main/aips/aip-113.md) to create a **Shelby Storage Account**. This enables cross-chain signatures to be managed flexibly and securely on the Aptos network. Read more about it [here](https://aptos.dev/build/sdks/wallet-adapter/x-chain-accounts).
|
|
53
|
-
|
|
54
|
-
The ownership hierarchy is:
|
|
55
|
-
|
|
56
|
-
- Solana keypair controls the Storage Account
|
|
57
|
-
- Storage Account owns the blobs on Shelby
|
|
58
|
-
|
|
59
|
-
### Create a Storage Account
|
|
60
|
-
|
|
61
|
-
The Shelby Storage Account is derived from:
|
|
62
|
-
|
|
63
|
-
- An original keypair. This links the main keypair with the storage account and ensures full ownership.
|
|
64
|
-
- A dApp domain. This maintains isolation at the application level. Since the storage account is based on the dApp domain, it is scoped to the dApp context. As a result, each storage account has a different address on different dApps.
|
|
65
|
-
|
|
66
|
-
```ts
|
|
67
|
-
import { Keypair } from "@solana/web3.js";
|
|
68
|
-
|
|
69
|
-
// Generate a Solana account
|
|
70
|
-
const solanaKeypair = Keypair.generate();
|
|
71
|
-
|
|
72
|
-
// The dApp domain. Most likely it is the deployed dApp website domain.
|
|
73
|
-
const domain = "my-awesome-dapp.com";
|
|
74
|
-
|
|
75
|
-
// Create a storage account controlled by the solana keypair
|
|
76
|
-
const storageAccount = shelbyClient.createStorageAccount(solanaKeypair, domain);
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
## Upload a Blob to Shelby
|
|
80
|
-
|
|
81
|
-
### Funding your account
|
|
82
|
-
|
|
83
|
-
To upload a file, the storage account needs to hold two assets:
|
|
84
|
-
|
|
85
|
-
- ShelbyUSD tokens: Used to pay for uploading the file to the Shelby devnet network
|
|
86
|
-
- APT tokens: Used to pay for gas fees when sending transactions
|
|
87
|
-
|
|
88
|
-
To fund your account with ShelbyUSD tokens, you can use the `fundAccountWithShelbyUSD()` function that the SDK provides.
|
|
89
|
-
|
|
90
|
-
```ts
|
|
91
|
-
// Fund the storage account with shelbyUSD (upload fees)
|
|
92
|
-
await shelbyClient.fundAccountWithShelbyUSD({
|
|
93
|
-
address: storageAccount.accountAddress,
|
|
94
|
-
amount: 1_000_000,
|
|
95
|
-
});
|
|
96
|
-
```
|
|
97
39
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
await shelbyClient.fundAccountWithAPT({
|
|
103
|
-
address: storageAccount.accountAddress,
|
|
104
|
-
amount: 1_000_000,
|
|
105
|
-
});
|
|
40
|
+
const storageAccount = shelbyClient.createStorageAccount(
|
|
41
|
+
Keypair.generate(),
|
|
42
|
+
"my-dapp.com"
|
|
43
|
+
);
|
|
106
44
|
```
|
|
107
45
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
```ts
|
|
111
|
-
import { Shelby, Network } from "@shelby-protocol/solana-kit/node";
|
|
112
|
-
import { Connection } from "@solana/web3.js";
|
|
46
|
+
See [Node.js README](./src/node/README.md) for detailed usage.
|
|
113
47
|
|
|
114
|
-
|
|
115
|
-
const connection = new Connection("https://api.devnet.solana.com");
|
|
116
|
-
|
|
117
|
-
// Create a shelby client
|
|
118
|
-
const shelbyClient = new Shelby({
|
|
119
|
-
network: Network.SHELBYNET,
|
|
120
|
-
connection,
|
|
121
|
-
apiKey: "AG-***",
|
|
122
|
-
// The Gas Station API Key
|
|
123
|
-
gasStationApiKey: "AG-***",
|
|
124
|
-
});
|
|
125
|
-
```
|
|
126
|
-
|
|
127
|
-
### Uploading a File
|
|
128
|
-
|
|
129
|
-
To upload a file, you can use the `upload()` function that the SDK provides.
|
|
130
|
-
|
|
131
|
-
```ts
|
|
132
|
-
// Generate a random blob name
|
|
133
|
-
const blobName = `example-${Math.floor(Math.random() * 900000 + 100000)}.txt`;
|
|
134
|
-
|
|
135
|
-
// Upload a blob to Shelby
|
|
136
|
-
await shelbyClient.upload({
|
|
137
|
-
blobData: new Uint8Array([1, 2, 3]),
|
|
138
|
-
signer: storageAccount,
|
|
139
|
-
blobName,
|
|
140
|
-
expirationMicros: Date.now() * 1000 + 86400000000, // 1 day
|
|
141
|
-
});
|
|
142
|
-
```
|
|
143
|
-
|
|
144
|
-
## React Integration
|
|
145
|
-
|
|
146
|
-
For React applications, use the `useStorageAccount` hook with `@solana/react-hooks`:
|
|
48
|
+
### React / Browser
|
|
147
49
|
|
|
148
50
|
```tsx
|
|
149
|
-
"use client";
|
|
150
|
-
|
|
151
51
|
import { useStorageAccount, Network } from "@shelby-protocol/solana-kit/react";
|
|
152
52
|
import { ShelbyClient } from "@shelby-protocol/sdk/browser";
|
|
153
53
|
import { useWalletConnection } from "@solana/react-hooks";
|
|
154
54
|
|
|
155
55
|
function MyComponent() {
|
|
156
56
|
const { wallet } = useWalletConnection();
|
|
157
|
-
const shelbyClient = new ShelbyClient({
|
|
158
|
-
network: Network.SHELBYNET,
|
|
159
|
-
apiKey: "AG-***",
|
|
160
|
-
});
|
|
57
|
+
const shelbyClient = new ShelbyClient({ network: Network.SHELBYNET, apiKey: "AG-***" });
|
|
161
58
|
|
|
162
59
|
const { storageAccountAddress, signAndSubmitTransaction } = useStorageAccount({
|
|
163
60
|
client: shelbyClient,
|
|
164
61
|
wallet,
|
|
165
62
|
});
|
|
166
63
|
|
|
167
|
-
|
|
168
|
-
<div>
|
|
169
|
-
<p>Storage Account: {storageAccountAddress?.toString()}</p>
|
|
170
|
-
</div>
|
|
171
|
-
);
|
|
64
|
+
// Storage account is automatically derived from the connected wallet
|
|
172
65
|
}
|
|
173
66
|
```
|
|
174
67
|
|
|
175
|
-
|
|
68
|
+
See [React README](./src/react/README.md) for detailed usage.
|
|
176
69
|
|
|
177
|
-
|
|
70
|
+
## Key Concepts
|
|
178
71
|
|
|
179
|
-
|
|
180
|
-
import { useWallet } from "@solana/wallet-adapter-react";
|
|
72
|
+
### Shelby Storage Account
|
|
181
73
|
|
|
182
|
-
|
|
183
|
-
const { publicKey, signMessage, signIn } = useWallet();
|
|
74
|
+
Shelby uses the Aptos blockchain as a coordination and settlement layer. To allow a Solana identity to own data in Shelby, the protocol leverages [Aptos Derivable Account Abstraction](https://github.com/aptos-foundation/AIPs/blob/main/aips/aip-113.md) to create a **Shelby Storage Account**.
|
|
184
75
|
|
|
185
|
-
|
|
186
|
-
client: shelbyClient,
|
|
187
|
-
wallet: publicKey
|
|
188
|
-
? {
|
|
189
|
-
account: { address: publicKey },
|
|
190
|
-
signMessage,
|
|
191
|
-
signIn,
|
|
192
|
-
}
|
|
193
|
-
: null,
|
|
194
|
-
});
|
|
76
|
+
This enables cross-chain signatures (SIWS - Sign-In with Solana) to be managed flexibly and securely on the Aptos network. Read more about it [here](https://aptos.dev/build/sdks/wallet-adapter/x-chain-accounts).
|
|
195
77
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
78
|
+
**Ownership hierarchy:**
|
|
79
|
+
|
|
80
|
+
- Solana keypair/wallet controls the Storage Account
|
|
81
|
+
- Storage Account owns the blobs on Shelby
|
|
82
|
+
|
|
83
|
+
**Address derivation:**
|
|
199
84
|
|
|
200
|
-
|
|
85
|
+
The storage account address is deterministically derived from:
|
|
86
|
+
1. The Solana public key
|
|
87
|
+
2. The dApp domain (e.g., `my-dapp.com`)
|
|
88
|
+
|
|
89
|
+
This means the same Solana wallet will have different storage accounts on different dApps, providing application-level isolation.
|
|
90
|
+
|
|
91
|
+
### Acquire a Shelby API Key
|
|
92
|
+
|
|
93
|
+
API keys authenticate your app and manage rate limits when using Shelby services. Without one, your client runs in "anonymous" mode with much lower limits.
|
|
94
|
+
|
|
95
|
+
Follow [this guide](https://docs.shelby.xyz/sdks/typescript/acquire-api-keys#acquiring-api-keys) to acquire an API Key.
|
|
96
|
+
|
|
97
|
+
## Retrieving Files
|
|
201
98
|
|
|
202
99
|
### Through Shelby Explorer
|
|
203
100
|
|
|
204
|
-
Once a blob has been uploaded to Shelby, it is viewable through the [Shelby Explorer](https://explorer.shelby.xyz/shelbynet).
|
|
205
|
-
Search for the storage account address to view the blobs owned by that account.
|
|
101
|
+
Once a blob has been uploaded to Shelby, it is viewable through the [Shelby Explorer](https://explorer.shelby.xyz/shelbynet). Search for the storage account address to view the blobs owned by that account.
|
|
206
102
|
|
|
207
|
-
###
|
|
103
|
+
### Via HTTP Request
|
|
208
104
|
|
|
209
|
-
|
|
105
|
+
Download files directly using a GET request to the Shelby RPC endpoint:
|
|
210
106
|
|
|
211
107
|
```bash
|
|
212
108
|
curl -X GET "https://api.shelbynet.shelby.xyz/shelby/v1/blobs/{account_address}/{blob_name}"
|
|
213
109
|
```
|
|
214
110
|
|
|
215
|
-
|
|
111
|
+
## Documentation
|
|
216
112
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
113
|
+
- [Node.js Usage](./src/node/README.md) - Server-side applications
|
|
114
|
+
- [React Usage](./src/react/README.md) - Browser applications
|
|
115
|
+
- [Full Documentation](https://docs.shelby.xyz/sdks/solana-kit)
|
package/dist/node/index.cjs
CHANGED
|
@@ -21,8 +21,8 @@ var _gasstationclient = require('@aptos-labs/gas-station-client');
|
|
|
21
21
|
|
|
22
22
|
|
|
23
23
|
// src/node/storageAccount.ts
|
|
24
|
-
|
|
25
|
-
var ShelbyStorageAccount = class extends
|
|
24
|
+
|
|
25
|
+
var ShelbyStorageAccount = class extends _derivedwalletsolana.SolanaDerivedAccount {
|
|
26
26
|
};
|
|
27
27
|
|
|
28
28
|
// src/node/shelby.ts
|
package/dist/node/index.d.cts
CHANGED
|
@@ -2,7 +2,7 @@ import { ShelbyNetwork, ShelbyClient } from '@shelby-protocol/sdk/node';
|
|
|
2
2
|
export * from '@shelby-protocol/sdk/node';
|
|
3
3
|
import { Network as Network$1 } from '@aptos-labs/ts-sdk';
|
|
4
4
|
import { Connection, Keypair } from '@solana/web3.js';
|
|
5
|
-
import { SolanaDerivedAccount } from '@aptos-labs/derived-wallet-solana
|
|
5
|
+
import { SolanaDerivedAccount } from '@aptos-labs/derived-wallet-solana';
|
|
6
6
|
|
|
7
7
|
declare const Network: {
|
|
8
8
|
readonly SHELBYNET: Network$1.SHELBYNET;
|
package/dist/node/index.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { ShelbyNetwork, ShelbyClient } from '@shelby-protocol/sdk/node';
|
|
|
2
2
|
export * from '@shelby-protocol/sdk/node';
|
|
3
3
|
import { Network as Network$1 } from '@aptos-labs/ts-sdk';
|
|
4
4
|
import { Connection, Keypair } from '@solana/web3.js';
|
|
5
|
-
import { SolanaDerivedAccount } from '@aptos-labs/derived-wallet-solana
|
|
5
|
+
import { SolanaDerivedAccount } from '@aptos-labs/derived-wallet-solana';
|
|
6
6
|
|
|
7
7
|
declare const Network: {
|
|
8
8
|
readonly SHELBYNET: Network$1.SHELBYNET;
|
package/dist/node/index.mjs
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
export * from "@shelby-protocol/sdk/node";
|
|
3
3
|
|
|
4
4
|
// src/common/constants.ts
|
|
5
|
-
import {
|
|
5
|
+
import { defaultSolanaAuthenticationFunction } from "@aptos-labs/derived-wallet-solana";
|
|
6
6
|
import { Network as AptosNetwork } from "@aptos-labs/ts-sdk";
|
|
7
7
|
var Network = {
|
|
8
8
|
SHELBYNET: AptosNetwork.SHELBYNET
|
|
@@ -10,7 +10,7 @@ var Network = {
|
|
|
10
10
|
|
|
11
11
|
// src/common/deriveAddress.ts
|
|
12
12
|
import {
|
|
13
|
-
|
|
13
|
+
defaultSolanaAuthenticationFunction as defaultSolanaAuthenticationFunction2,
|
|
14
14
|
SolanaDerivedPublicKey
|
|
15
15
|
} from "@aptos-labs/derived-wallet-solana";
|
|
16
16
|
|
|
@@ -21,7 +21,7 @@ import {
|
|
|
21
21
|
} from "@shelby-protocol/sdk/node";
|
|
22
22
|
|
|
23
23
|
// src/node/storageAccount.ts
|
|
24
|
-
import { SolanaDerivedAccount } from "@aptos-labs/derived-wallet-solana
|
|
24
|
+
import { SolanaDerivedAccount } from "@aptos-labs/derived-wallet-solana";
|
|
25
25
|
var ShelbyStorageAccount = class extends SolanaDerivedAccount {
|
|
26
26
|
};
|
|
27
27
|
|
package/dist/react/index.d.ts
CHANGED
|
@@ -49,4 +49,4 @@ interface UseStorageAccountResult {
|
|
|
49
49
|
}
|
|
50
50
|
declare function useStorageAccount(params: UseStorageAccountParams): UseStorageAccountResult;
|
|
51
51
|
|
|
52
|
-
export { Network, type SignAndSubmitTransactionInput, type SignTransactionInput, type SubmitTransactionInput, type UseStorageAccountParams, type UseStorageAccountResult, useStorageAccount };
|
|
52
|
+
export { Network, type SignAndSubmitTransactionInput, type SignTransactionInput, type SolanaWallet, type SubmitTransactionInput, type UseStorageAccountParams, type UseStorageAccountResult, useStorageAccount };
|
package/dist/react/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/common/constants.ts
|
|
2
|
-
import {
|
|
2
|
+
import { defaultSolanaAuthenticationFunction } from "@aptos-labs/derived-wallet-solana";
|
|
3
3
|
import { Network as AptosNetwork } from "@aptos-labs/ts-sdk";
|
|
4
4
|
var Network = {
|
|
5
5
|
SHELBYNET: AptosNetwork.SHELBYNET
|
|
@@ -7,13 +7,13 @@ var Network = {
|
|
|
7
7
|
|
|
8
8
|
// src/common/deriveAddress.ts
|
|
9
9
|
import {
|
|
10
|
-
|
|
10
|
+
defaultSolanaAuthenticationFunction as defaultSolanaAuthenticationFunction2,
|
|
11
11
|
SolanaDerivedPublicKey
|
|
12
12
|
} from "@aptos-labs/derived-wallet-solana";
|
|
13
13
|
|
|
14
14
|
// src/react/useStorageAccount.tsx
|
|
15
15
|
import {
|
|
16
|
-
|
|
16
|
+
defaultSolanaAuthenticationFunction as defaultSolanaAuthenticationFunction3,
|
|
17
17
|
SolanaDerivedPublicKey as SolanaDerivedPublicKey2,
|
|
18
18
|
signAptosTransactionWithSolana
|
|
19
19
|
} from "@aptos-labs/derived-wallet-solana";
|
|
@@ -26,23 +26,30 @@ function useStorageAccount(params) {
|
|
|
26
26
|
const publicKey = wallet?.account?.address?.toString() ?? null;
|
|
27
27
|
const derivedPublicKey = useMemo(() => {
|
|
28
28
|
if (!publicKey || !domain) return null;
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
29
|
+
try {
|
|
30
|
+
return new SolanaDerivedPublicKey2({
|
|
31
|
+
domain,
|
|
32
|
+
solanaPublicKey: new PublicKey(publicKey),
|
|
33
|
+
authenticationFunction: defaultSolanaAuthenticationFunction3
|
|
34
|
+
});
|
|
35
|
+
} catch {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
34
38
|
}, [publicKey, domain]);
|
|
35
39
|
const storageAccountAddress = useMemo(
|
|
36
40
|
() => derivedPublicKey?.authKey().derivedAddress() ?? null,
|
|
37
41
|
[derivedPublicKey]
|
|
38
42
|
);
|
|
39
43
|
const signTransaction = async (params2) => {
|
|
40
|
-
if (!storageAccountAddress) {
|
|
41
|
-
throw new Error("Storage account address not found");
|
|
42
|
-
}
|
|
43
44
|
if (!publicKey) {
|
|
44
45
|
throw new Error("Wallet not connected");
|
|
45
46
|
}
|
|
47
|
+
if (!derivedPublicKey) {
|
|
48
|
+
throw new Error("Invalid Solana public key");
|
|
49
|
+
}
|
|
50
|
+
if (!storageAccountAddress) {
|
|
51
|
+
throw new Error("Storage account address not found");
|
|
52
|
+
}
|
|
46
53
|
const rawTransaction = await client.aptos.transaction.build.simple({
|
|
47
54
|
sender: storageAccountAddress,
|
|
48
55
|
data: params2.data
|
|
@@ -57,7 +64,7 @@ function useStorageAccount(params) {
|
|
|
57
64
|
signIn: wallet?.signIn,
|
|
58
65
|
name: "Solana Wallet"
|
|
59
66
|
},
|
|
60
|
-
authenticationFunction:
|
|
67
|
+
authenticationFunction: defaultSolanaAuthenticationFunction3,
|
|
61
68
|
rawTransaction,
|
|
62
69
|
domain
|
|
63
70
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shelby-protocol/solana-kit",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
}
|
|
48
48
|
},
|
|
49
49
|
"dependencies": {
|
|
50
|
-
"@aptos-labs/derived-wallet-solana": "0.
|
|
50
|
+
"@aptos-labs/derived-wallet-solana": "^0.12.0",
|
|
51
51
|
"@aptos-labs/gas-station-client": "^2.0.3",
|
|
52
52
|
"@aptos-labs/ts-sdk": "^5.1.1",
|
|
53
53
|
"@aptos-labs/wallet-standard": "^0.5.2",
|