@shelby-protocol/solana-kit 0.0.1

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 ADDED
@@ -0,0 +1,159 @@
1
+ # Solana Kit for the Shelby Protocol
2
+
3
+ > Note: The SDK is currently an alpha version; therefore, you can expect breaking changes.
4
+
5
+ Shelby is a high-performance decentralized blob storage system designed for demanding read-heavy workloads. Read more about Shelby, its capabilities, and components [here](https://docs.shelby.xyz/protocol).
6
+
7
+ The Solana Kit SDK was built to facilitate the development of Solana applications that use the Shelby Protocol.
8
+
9
+ ## Installation
10
+
11
+ Install with your favorite package manager such as npm, yarn, or pnpm:
12
+
13
+ ```bash
14
+ pnpm install @shelby-protocol/solana-kit
15
+ ```
16
+
17
+ ## Acquire a Shelby API Key
18
+
19
+ 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, which can affect performance.
20
+
21
+ Follow [this guide](https://docs.shelby.xyz/sdks/typescript/acquire-api-keys#acquiring-api-keys) to acquire an API Key.
22
+
23
+ ## Usage
24
+
25
+ Create a `Shelby` client in order to access the SDK's functionality.
26
+
27
+ ```ts
28
+ import { Shelby, Network } from "@shelby-protocol/solana-kit/node";
29
+ import { Connection } from "@solana/web3.js";
30
+
31
+ // Create a Solana network connection
32
+ const connection = new Connection("https://api.devnet.solana.com");
33
+
34
+ // Create a shelby client
35
+ const shelbyClient = new Shelby({
36
+ // The Shelby network to connect with
37
+ network: Network.SHELBYNET,
38
+ connection,
39
+ // The Shelby API Key
40
+ apiKey: "AG-***",
41
+ });
42
+ ```
43
+
44
+ ## Shelby Storage Account
45
+
46
+ 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.
47
+
48
+ 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).
49
+
50
+ The ownership hierarchy is:
51
+
52
+ - Solana keypair controls the Storage Account
53
+ - Storage Account owns the blobs on Shelby
54
+
55
+ ### Create a Storage Account
56
+
57
+ The Shelby Storage Account is derived from:
58
+
59
+ - An original keypair. This links the main keypair with the storage account and ensures full ownership.
60
+ - 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.
61
+
62
+ ```ts
63
+ import { Keypair } from "@solana/web3.js";
64
+
65
+ // Generate a Solana account
66
+ const solanaKeypair = Keypair.generate();
67
+
68
+ // The dApp domain. Most likely it is the deployed dApp website domain.
69
+ const domain = "my-awesome-dapp.com";
70
+
71
+ // Create a storage account controlled by the solana keypair
72
+ const storageAccount = shelbyClient.createStorageAccount(solanaKeypair, domain);
73
+ ```
74
+
75
+ ## Upload a Blob to Shelby
76
+
77
+ ### Funding your account
78
+
79
+ To upload a file, the storage account needs to hold two assets:
80
+
81
+ - ShelbyUSD tokens: Used to pay for uploading the file to the Shelby devnet network
82
+ - APT tokens: Used to pay for gas fees when sending transactions
83
+
84
+ To fund your account with ShelbyUSD tokens, you can use the `fundAccountWithShelbyUSD()` function that the SDK provides.
85
+
86
+ ```ts
87
+ // Fund the storage account with shelbyUSD (upload fees)
88
+ await shelbyClient.fundAccountWithShelbyUSD({
89
+ address: storageAccount.accountAddress,
90
+ amount: 1_000_000,
91
+ });
92
+ ```
93
+
94
+ To fund your account with APT tokens, you can use the `fundAccountWithAPT()` function that the SDK provides.
95
+
96
+ ```ts
97
+ // Fund the storage account with APT (transaction fees)
98
+ await shelbyClient.fundAccountWithAPT({
99
+ address: storageAccount.accountAddress,
100
+ amount: 1_000_000,
101
+ });
102
+ ```
103
+
104
+ > Note: Alternatively, instead of funding your storage account with APT, you can use [Geomi Gas Station](https://geomi.dev/docs/gas-stations) to sponsor the transaction fees.
105
+
106
+ ```ts
107
+ import { Shelby, Network } from "@shelby-protocol/solana-kit/node";
108
+ import { Connection } from "@solana/web3.js";
109
+
110
+ // Create a Solana network connection
111
+ const connection = new Connection("https://api.devnet.solana.com");
112
+
113
+ // Create a shelby client
114
+ const shelbyClient = new Shelby({
115
+ network: Network.SHELBYNET,
116
+ connection,
117
+ apiKey: "AG-***",
118
+ // The Gas Station API Key
119
+ gasStationApiKey: "AG-***",
120
+ });
121
+ ```
122
+
123
+ ### Uploading a File
124
+
125
+ To upload a file, you can use the `upload()` function that the SDK provides.
126
+
127
+ ```ts
128
+ // Generate a random blob name
129
+ const blobName = `example-${Math.floor(Math.random() * 900000 + 100000)}.txt`;
130
+
131
+ // Upload a blob to Shelby
132
+ await shelbyClient.upload({
133
+ blobData: new Uint8Array([1, 2, 3]),
134
+ signer: storageAccount,
135
+ blobName,
136
+ expirationMicros: Date.now() * 1000 + 86400000000, // 1 day
137
+ });
138
+ ```
139
+
140
+ ## Retrieving a file
141
+
142
+ ### Through Shelby Explorer
143
+
144
+ Once a blob has been uploaded to Shelby, it is viewable through the [Shelby Explorer](https://explorer.shelby.xyz/shelbynet).
145
+ Search for the storage account address to view the blobs owned by that account.
146
+
147
+ ### GET request
148
+
149
+ Alternatively, you can directly download the file using a GET request to the Shelby RPC endpoint.
150
+
151
+ ```bash
152
+ curl -X GET "https://api.shelbynet.shelby.xyz/shelby/v1/blobs/{account_address}/{blob_name}"
153
+ ```
154
+
155
+ With the previous example, the file should be available at
156
+
157
+ ```bash
158
+ curl -X GET `https://api.shelbynet.shelby.xyz/shelby/v1/blobs/${storageAccount.accountAddress.toString()}/${blobName}`;
159
+ ```
@@ -0,0 +1,116 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }// src/node/index.ts
2
+ var _tssdk = require('@aptos-labs/ts-sdk');
3
+
4
+ // src/node/shelby.ts
5
+ var _gasstationclient = require('@aptos-labs/gas-station-client');
6
+
7
+
8
+ var _node = require('@shelby-protocol/sdk/node');
9
+
10
+ // src/node/storageAccount.ts
11
+
12
+
13
+
14
+
15
+ var _derivedwalletsolana = require('@aptos-labs/derived-wallet-solana');
16
+
17
+
18
+
19
+ var _walletstandardutil = require('@solana/wallet-standard-util');
20
+ var _tweetnacl = require('tweetnacl'); var _tweetnacl2 = _interopRequireDefault(_tweetnacl);
21
+ var ShelbyStorageAccount = class extends _tssdk.AbstractedAccount {
22
+ constructor(params) {
23
+ const { solanaKeypair, domain, authenticationFunction } = params;
24
+ const derivedPublicKey = new (0, _derivedwalletsolana.SolanaDerivedPublicKey)({
25
+ domain,
26
+ solanaPublicKey: solanaKeypair.publicKey,
27
+ authenticationFunction
28
+ });
29
+ super({
30
+ accountAddress: derivedPublicKey.authKey().derivedAddress(),
31
+ authenticationFunction,
32
+ signer: (digest) => {
33
+ return _tweetnacl2.default.sign.detached(
34
+ digest,
35
+ solanaKeypair.secretKey
36
+ );
37
+ }
38
+ });
39
+ this.solanaKeypair = solanaKeypair;
40
+ this.domain = domain;
41
+ this.derivedPublicKey = derivedPublicKey;
42
+ }
43
+ /**
44
+ * Override the transaction signing to use SIWS envelope format
45
+ */
46
+ signTransactionWithAuthenticator(transaction) {
47
+ const { siwsInput, signingMessageDigest } = _derivedwalletsolana.createMessageForSolanaTransaction.call(void 0, {
48
+ rawTransaction: transaction,
49
+ authenticationFunction: this.authenticationFunction,
50
+ solanaPublicKey: this.solanaKeypair.publicKey,
51
+ domain: this.domain
52
+ });
53
+ const messageToSign = _walletstandardutil.createSignInMessage.call(void 0, siwsInput);
54
+ const signatureBytes = _tweetnacl2.default.sign.detached(
55
+ messageToSign,
56
+ this.solanaKeypair.secretKey
57
+ );
58
+ return _derivedwalletsolana.createAccountAuthenticatorForSolanaTransaction.call(void 0,
59
+ signatureBytes,
60
+ this.solanaKeypair.publicKey,
61
+ this.domain,
62
+ this.authenticationFunction,
63
+ signingMessageDigest
64
+ );
65
+ }
66
+ };
67
+
68
+ // src/node/shelby.ts
69
+ var Shelby = class extends _node.ShelbyClient {
70
+ constructor(params) {
71
+ const shelbyClientConfig = {
72
+ network: params.network,
73
+ apiKey: params.apiKey
74
+ };
75
+ if (params.gasStationApiKey) {
76
+ shelbyClientConfig.aptos = {
77
+ pluginSettings: {
78
+ TRANSACTION_SUBMITTER: new (0, _gasstationclient.GasStationTransactionSubmitter)({
79
+ network: params.network,
80
+ apiKey: params.gasStationApiKey
81
+ })
82
+ }
83
+ };
84
+ }
85
+ super(shelbyClientConfig);
86
+ this.connection = params.connection;
87
+ }
88
+ /**
89
+ * Create a Shelby storage account
90
+ *
91
+ * @param solanaKeypair - The Solana keypair
92
+ * @param domain - The domain of the storage account
93
+ * @returns The Shelby storage account
94
+ *
95
+ * @example
96
+ * ```typescript
97
+ * const storageAccount = shelbyClient.createStorageAccount(solanaKeypair, domain);
98
+ * ```
99
+ */
100
+ createStorageAccount(solanaKeypair, domain) {
101
+ return new ShelbyStorageAccount({
102
+ solanaKeypair,
103
+ domain,
104
+ authenticationFunction: "0x1::solana_derivable_account::authenticate"
105
+ });
106
+ }
107
+ };
108
+
109
+ // src/node/index.ts
110
+ var Network = {
111
+ SHELBYNET: _tssdk.Network.SHELBYNET
112
+ };
113
+
114
+
115
+
116
+ exports.Network = Network; exports.Shelby = Shelby;
@@ -0,0 +1,80 @@
1
+ import { AbstractedAccount, AnyRawTransaction, AccountAuthenticatorAbstraction, Network as Network$1 } from '@aptos-labs/ts-sdk';
2
+ import { ShelbyNetwork, ShelbyClient } from '@shelby-protocol/sdk/node';
3
+ import { Keypair, Connection } from '@solana/web3.js';
4
+ import { SolanaDerivedPublicKey } from '@aptos-labs/derived-wallet-solana';
5
+
6
+ /**
7
+ * A Shelby storage account that can be used as a signer for transactions on the Shelby network
8
+ *
9
+ * @param params - The parameters for the Shelby storage account
10
+ * @param params.solanaKeypair - The Solana keypair
11
+ * @param params.domain - The domain of the storage account
12
+ * @param params.authenticationFunction - The authentication function
13
+ * @example
14
+ * ```typescript
15
+ * const storageAccount = new ShelbyStorageAccount({
16
+ * solanaKeypair: solanaKeypair,
17
+ * domain: "my-awesome-dapp.com",
18
+ * authenticationFunction: "0x1::solana_derivable_account::authenticate",
19
+ * });
20
+ * ```
21
+ */
22
+ declare class ShelbyStorageAccount extends AbstractedAccount {
23
+ readonly solanaKeypair: Keypair;
24
+ readonly domain: string;
25
+ readonly derivedPublicKey: SolanaDerivedPublicKey;
26
+ constructor(params: {
27
+ solanaKeypair: Keypair;
28
+ domain: string;
29
+ authenticationFunction: string;
30
+ });
31
+ /**
32
+ * Override the transaction signing to use SIWS envelope format
33
+ */
34
+ signTransactionWithAuthenticator(transaction: AnyRawTransaction): AccountAuthenticatorAbstraction;
35
+ }
36
+
37
+ interface ShelbyParams {
38
+ network: ShelbyNetwork;
39
+ connection: Connection;
40
+ apiKey: string;
41
+ gasStationApiKey?: string;
42
+ }
43
+ /**
44
+ * The Shelby client for the Solana network
45
+ *
46
+ * @param params - The parameters for the Shelby client
47
+ *
48
+ * @example
49
+ * ```typescript
50
+ * const shelbyClient = new Shelby({
51
+ * network: Network.SHELBYNET,
52
+ * connection: new Connection("https://api.devnet.solana.com"),
53
+ * apiKey: "AG-***",
54
+ * });
55
+ * ```
56
+ */
57
+ declare class Shelby extends ShelbyClient {
58
+ private readonly connection;
59
+ constructor(params: ShelbyParams);
60
+ /**
61
+ * Create a Shelby storage account
62
+ *
63
+ * @param solanaKeypair - The Solana keypair
64
+ * @param domain - The domain of the storage account
65
+ * @returns The Shelby storage account
66
+ *
67
+ * @example
68
+ * ```typescript
69
+ * const storageAccount = shelbyClient.createStorageAccount(solanaKeypair, domain);
70
+ * ```
71
+ */
72
+ createStorageAccount(solanaKeypair: Keypair, domain: string): ShelbyStorageAccount;
73
+ }
74
+
75
+ declare const Network: {
76
+ readonly SHELBYNET: Network$1.SHELBYNET;
77
+ };
78
+ type Network = (typeof Network)[keyof typeof Network];
79
+
80
+ export { Network, Shelby, type ShelbyParams };
@@ -0,0 +1,80 @@
1
+ import { AbstractedAccount, AnyRawTransaction, AccountAuthenticatorAbstraction, Network as Network$1 } from '@aptos-labs/ts-sdk';
2
+ import { ShelbyNetwork, ShelbyClient } from '@shelby-protocol/sdk/node';
3
+ import { Keypair, Connection } from '@solana/web3.js';
4
+ import { SolanaDerivedPublicKey } from '@aptos-labs/derived-wallet-solana';
5
+
6
+ /**
7
+ * A Shelby storage account that can be used as a signer for transactions on the Shelby network
8
+ *
9
+ * @param params - The parameters for the Shelby storage account
10
+ * @param params.solanaKeypair - The Solana keypair
11
+ * @param params.domain - The domain of the storage account
12
+ * @param params.authenticationFunction - The authentication function
13
+ * @example
14
+ * ```typescript
15
+ * const storageAccount = new ShelbyStorageAccount({
16
+ * solanaKeypair: solanaKeypair,
17
+ * domain: "my-awesome-dapp.com",
18
+ * authenticationFunction: "0x1::solana_derivable_account::authenticate",
19
+ * });
20
+ * ```
21
+ */
22
+ declare class ShelbyStorageAccount extends AbstractedAccount {
23
+ readonly solanaKeypair: Keypair;
24
+ readonly domain: string;
25
+ readonly derivedPublicKey: SolanaDerivedPublicKey;
26
+ constructor(params: {
27
+ solanaKeypair: Keypair;
28
+ domain: string;
29
+ authenticationFunction: string;
30
+ });
31
+ /**
32
+ * Override the transaction signing to use SIWS envelope format
33
+ */
34
+ signTransactionWithAuthenticator(transaction: AnyRawTransaction): AccountAuthenticatorAbstraction;
35
+ }
36
+
37
+ interface ShelbyParams {
38
+ network: ShelbyNetwork;
39
+ connection: Connection;
40
+ apiKey: string;
41
+ gasStationApiKey?: string;
42
+ }
43
+ /**
44
+ * The Shelby client for the Solana network
45
+ *
46
+ * @param params - The parameters for the Shelby client
47
+ *
48
+ * @example
49
+ * ```typescript
50
+ * const shelbyClient = new Shelby({
51
+ * network: Network.SHELBYNET,
52
+ * connection: new Connection("https://api.devnet.solana.com"),
53
+ * apiKey: "AG-***",
54
+ * });
55
+ * ```
56
+ */
57
+ declare class Shelby extends ShelbyClient {
58
+ private readonly connection;
59
+ constructor(params: ShelbyParams);
60
+ /**
61
+ * Create a Shelby storage account
62
+ *
63
+ * @param solanaKeypair - The Solana keypair
64
+ * @param domain - The domain of the storage account
65
+ * @returns The Shelby storage account
66
+ *
67
+ * @example
68
+ * ```typescript
69
+ * const storageAccount = shelbyClient.createStorageAccount(solanaKeypair, domain);
70
+ * ```
71
+ */
72
+ createStorageAccount(solanaKeypair: Keypair, domain: string): ShelbyStorageAccount;
73
+ }
74
+
75
+ declare const Network: {
76
+ readonly SHELBYNET: Network$1.SHELBYNET;
77
+ };
78
+ type Network = (typeof Network)[keyof typeof Network];
79
+
80
+ export { Network, Shelby, type ShelbyParams };
@@ -0,0 +1,116 @@
1
+ // src/node/index.ts
2
+ import { Network as AptosNetwork } from "@aptos-labs/ts-sdk";
3
+
4
+ // src/node/shelby.ts
5
+ import { GasStationTransactionSubmitter } from "@aptos-labs/gas-station-client";
6
+ import {
7
+ ShelbyClient
8
+ } from "@shelby-protocol/sdk/node";
9
+
10
+ // src/node/storageAccount.ts
11
+ import {
12
+ createAccountAuthenticatorForSolanaTransaction,
13
+ createMessageForSolanaTransaction,
14
+ SolanaDerivedPublicKey
15
+ } from "@aptos-labs/derived-wallet-solana";
16
+ import {
17
+ AbstractedAccount
18
+ } from "@aptos-labs/ts-sdk";
19
+ import { createSignInMessage } from "@solana/wallet-standard-util";
20
+ import nacl from "tweetnacl";
21
+ var ShelbyStorageAccount = class extends AbstractedAccount {
22
+ constructor(params) {
23
+ const { solanaKeypair, domain, authenticationFunction } = params;
24
+ const derivedPublicKey = new SolanaDerivedPublicKey({
25
+ domain,
26
+ solanaPublicKey: solanaKeypair.publicKey,
27
+ authenticationFunction
28
+ });
29
+ super({
30
+ accountAddress: derivedPublicKey.authKey().derivedAddress(),
31
+ authenticationFunction,
32
+ signer: (digest) => {
33
+ return nacl.sign.detached(
34
+ digest,
35
+ solanaKeypair.secretKey
36
+ );
37
+ }
38
+ });
39
+ this.solanaKeypair = solanaKeypair;
40
+ this.domain = domain;
41
+ this.derivedPublicKey = derivedPublicKey;
42
+ }
43
+ /**
44
+ * Override the transaction signing to use SIWS envelope format
45
+ */
46
+ signTransactionWithAuthenticator(transaction) {
47
+ const { siwsInput, signingMessageDigest } = createMessageForSolanaTransaction({
48
+ rawTransaction: transaction,
49
+ authenticationFunction: this.authenticationFunction,
50
+ solanaPublicKey: this.solanaKeypair.publicKey,
51
+ domain: this.domain
52
+ });
53
+ const messageToSign = createSignInMessage(siwsInput);
54
+ const signatureBytes = nacl.sign.detached(
55
+ messageToSign,
56
+ this.solanaKeypair.secretKey
57
+ );
58
+ return createAccountAuthenticatorForSolanaTransaction(
59
+ signatureBytes,
60
+ this.solanaKeypair.publicKey,
61
+ this.domain,
62
+ this.authenticationFunction,
63
+ signingMessageDigest
64
+ );
65
+ }
66
+ };
67
+
68
+ // src/node/shelby.ts
69
+ var Shelby = class extends ShelbyClient {
70
+ constructor(params) {
71
+ const shelbyClientConfig = {
72
+ network: params.network,
73
+ apiKey: params.apiKey
74
+ };
75
+ if (params.gasStationApiKey) {
76
+ shelbyClientConfig.aptos = {
77
+ pluginSettings: {
78
+ TRANSACTION_SUBMITTER: new GasStationTransactionSubmitter({
79
+ network: params.network,
80
+ apiKey: params.gasStationApiKey
81
+ })
82
+ }
83
+ };
84
+ }
85
+ super(shelbyClientConfig);
86
+ this.connection = params.connection;
87
+ }
88
+ /**
89
+ * Create a Shelby storage account
90
+ *
91
+ * @param solanaKeypair - The Solana keypair
92
+ * @param domain - The domain of the storage account
93
+ * @returns The Shelby storage account
94
+ *
95
+ * @example
96
+ * ```typescript
97
+ * const storageAccount = shelbyClient.createStorageAccount(solanaKeypair, domain);
98
+ * ```
99
+ */
100
+ createStorageAccount(solanaKeypair, domain) {
101
+ return new ShelbyStorageAccount({
102
+ solanaKeypair,
103
+ domain,
104
+ authenticationFunction: "0x1::solana_derivable_account::authenticate"
105
+ });
106
+ }
107
+ };
108
+
109
+ // src/node/index.ts
110
+ var Network = {
111
+ SHELBYNET: AptosNetwork.SHELBYNET
112
+ };
113
+ export {
114
+ Network,
115
+ Shelby
116
+ };
package/package.json ADDED
@@ -0,0 +1,46 @@
1
+ {
2
+ "name": "@shelby-protocol/solana-kit",
3
+ "version": "0.0.1",
4
+ "private": false,
5
+ "publishConfig": {
6
+ "access": "public"
7
+ },
8
+ "type": "module",
9
+ "files": [
10
+ "dist"
11
+ ],
12
+ "exports": {
13
+ "./node": {
14
+ "types": "./dist/node/index.d.ts",
15
+ "import": "./dist/node/index.mjs",
16
+ "require": "./dist/node/index.cjs"
17
+ }
18
+ },
19
+ "scripts": {
20
+ "lint": "biome check .",
21
+ "fmt": "biome check . --write",
22
+ "build": "tsc --noEmit && (rimraf dist; tsup)",
23
+ "test": "vitest dev",
24
+ "test:once": "vitest run"
25
+ },
26
+ "devDependencies": {
27
+ "@biomejs/biome": "2.0.6",
28
+ "@solana/web3.js": "^1.98.4",
29
+ "rimraf": "^6.0.1",
30
+ "tsup": "^8.4.0",
31
+ "typescript": "^5.8.3",
32
+ "vitest": "^3.1.2"
33
+ },
34
+ "peerDependencies": {
35
+ "@solana/web3.js": "^1.98.4"
36
+ },
37
+ "dependencies": {
38
+ "@aptos-labs/derived-wallet-base": "^0.10.0",
39
+ "@aptos-labs/derived-wallet-solana": "^0.9.1",
40
+ "@aptos-labs/gas-station-client": "^2.0.3",
41
+ "@aptos-labs/ts-sdk": "^5.1.1",
42
+ "@shelby-protocol/sdk": "workspace:*",
43
+ "@solana/wallet-standard-util": "^1.1.2",
44
+ "tweetnacl": "^1.0.3"
45
+ }
46
+ }