@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 +159 -0
- package/dist/node/index.cjs +116 -0
- package/dist/node/index.d.cts +80 -0
- package/dist/node/index.d.ts +80 -0
- package/dist/node/index.mjs +116 -0
- package/package.json +46 -0
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
|
+
}
|