ryt-sdk 1.0.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 +8 -0
- package/dist/config.d.ts +39 -0
- package/dist/config.js +37 -0
- package/dist/contract.d.ts +142 -0
- package/dist/contract.js +208 -0
- package/dist/index.d.ts +38 -0
- package/dist/index.js +38 -0
- package/dist/provider.d.ts +49 -0
- package/dist/provider.js +62 -0
- package/dist/wallet.d.ts +63 -0
- package/dist/wallet.js +81 -0
- package/package.json +61 -0
package/README.md
ADDED
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration options for initializing the RYT SDK
|
|
3
|
+
*/
|
|
4
|
+
export interface SDKConfig {
|
|
5
|
+
/**
|
|
6
|
+
* Chain ID of the target blockchain network
|
|
7
|
+
* @example 1 (Ethereum Mainnet), 137 (Polygon)
|
|
8
|
+
*/
|
|
9
|
+
chainId: number;
|
|
10
|
+
/**
|
|
11
|
+
* List of RPC endpoints used to communicate with the blockchain
|
|
12
|
+
* The SDK may use fallback logic if multiple URLs are provided
|
|
13
|
+
* @example ["https://rpc1.example.com", "https://rpc2.example.com"]
|
|
14
|
+
*/
|
|
15
|
+
rpcUrls: string[];
|
|
16
|
+
/**
|
|
17
|
+
* Optional block explorer base URL for the network
|
|
18
|
+
* Used to generate transaction/address links if provided
|
|
19
|
+
* @example "https://etherscan.io"
|
|
20
|
+
*/
|
|
21
|
+
explorer?: string;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Validates and normalizes SDK configuration
|
|
25
|
+
*
|
|
26
|
+
* @param config - User-provided SDK configuration
|
|
27
|
+
* @returns Validated and normalized configuration
|
|
28
|
+
*
|
|
29
|
+
* @throws Error if required fields are missing or invalid
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* ```ts
|
|
33
|
+
* const config = validateConfig({
|
|
34
|
+
* chainId: 1234,
|
|
35
|
+
* rpcUrls: ["http://localhost:8545"]
|
|
36
|
+
* });
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
export declare function validateConfig(config: SDKConfig): SDKConfig;
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validates and normalizes SDK configuration
|
|
3
|
+
*
|
|
4
|
+
* @param config - User-provided SDK configuration
|
|
5
|
+
* @returns Validated and normalized configuration
|
|
6
|
+
*
|
|
7
|
+
* @throws Error if required fields are missing or invalid
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* const config = validateConfig({
|
|
12
|
+
* chainId: 1234,
|
|
13
|
+
* rpcUrls: ["http://localhost:8545"]
|
|
14
|
+
* });
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
export function validateConfig(config) {
|
|
18
|
+
if (!config) {
|
|
19
|
+
throw new Error("SDK config is required");
|
|
20
|
+
}
|
|
21
|
+
if (typeof config.chainId !== "number" || isNaN(config.chainId)) {
|
|
22
|
+
throw new Error("Invalid chainId: must be a valid number");
|
|
23
|
+
}
|
|
24
|
+
if (!Array.isArray(config.rpcUrls) || config.rpcUrls.length === 0) {
|
|
25
|
+
throw new Error("rpcUrls must be a non-empty array");
|
|
26
|
+
}
|
|
27
|
+
for (const url of config.rpcUrls) {
|
|
28
|
+
if (typeof url !== "string" || !url.startsWith("http")) {
|
|
29
|
+
throw new Error(`Invalid RPC URL: ${url}`);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
if (config.explorer !== undefined &&
|
|
33
|
+
(typeof config.explorer !== "string" || config.explorer.length === 0)) {
|
|
34
|
+
throw new Error("explorer must be a valid URL string if provided");
|
|
35
|
+
}
|
|
36
|
+
return config;
|
|
37
|
+
}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { ethers } from "ethers";
|
|
2
|
+
import RYTWallet from "./wallet";
|
|
3
|
+
/**
|
|
4
|
+
* -----------------------------
|
|
5
|
+
* Library Linking Types
|
|
6
|
+
* -----------------------------
|
|
7
|
+
*/
|
|
8
|
+
export interface LinkReferences {
|
|
9
|
+
[file: string]: {
|
|
10
|
+
[libraryName: string]: Array<{
|
|
11
|
+
start: number;
|
|
12
|
+
length: number;
|
|
13
|
+
}>;
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Options for standard contract deployment (CREATE)
|
|
18
|
+
*/
|
|
19
|
+
export interface DeployOptions {
|
|
20
|
+
/** Contract ABI */
|
|
21
|
+
abi: any[];
|
|
22
|
+
/** Compiled bytecode */
|
|
23
|
+
bytecode: string;
|
|
24
|
+
/** Constructor arguments */
|
|
25
|
+
args?: any[];
|
|
26
|
+
/** ETH value to send */
|
|
27
|
+
value?: bigint | number;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Options for CREATE2 deployment
|
|
31
|
+
*/
|
|
32
|
+
export interface Create2DeployOptions extends DeployOptions {
|
|
33
|
+
/** Factory contract address */
|
|
34
|
+
factoryAddress: string;
|
|
35
|
+
/** Salt for deterministic address */
|
|
36
|
+
salt: string;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Options for UUPS / ERC1967 proxy deployment
|
|
40
|
+
*/
|
|
41
|
+
export interface UUPSDeployOptions {
|
|
42
|
+
/** Implementation ABI */
|
|
43
|
+
implementationAbi: any[];
|
|
44
|
+
/** Implementation bytecode */
|
|
45
|
+
implementationBytecode: string;
|
|
46
|
+
/** Initialization calldata */
|
|
47
|
+
initData?: string;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Options for library-linked deployment
|
|
51
|
+
*/
|
|
52
|
+
export interface LibraryDeployOptions {
|
|
53
|
+
/** Contract ABI */
|
|
54
|
+
abi: any[];
|
|
55
|
+
/** Contract bytecode */
|
|
56
|
+
bytecode: string;
|
|
57
|
+
/** Solidity link references */
|
|
58
|
+
linkReferences: LinkReferences;
|
|
59
|
+
/** Library addresses mapping */
|
|
60
|
+
libraries?: Record<string, string>;
|
|
61
|
+
/** Constructor arguments */
|
|
62
|
+
args?: any[];
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* ----------------------------------------------------
|
|
66
|
+
* RYTContract - Core smart contract interaction layer
|
|
67
|
+
* ----------------------------------------------------
|
|
68
|
+
*
|
|
69
|
+
* Supports:
|
|
70
|
+
* - Read / Write contract calls
|
|
71
|
+
* - CREATE deployment
|
|
72
|
+
* - CREATE2 deployment
|
|
73
|
+
* - Minimal proxy (EIP-1167)
|
|
74
|
+
* - UUPS / ERC1967 proxy deployment
|
|
75
|
+
* - Library-linked deployment
|
|
76
|
+
*/
|
|
77
|
+
export default class RYTContract {
|
|
78
|
+
private wallet;
|
|
79
|
+
contract: ethers.Contract | null;
|
|
80
|
+
/**
|
|
81
|
+
* Create a new contract instance
|
|
82
|
+
*
|
|
83
|
+
* @param address - deployed contract address (optional)
|
|
84
|
+
* @param abi - contract ABI
|
|
85
|
+
* @param signerOrProvider - wallet or provider instance
|
|
86
|
+
*/
|
|
87
|
+
constructor(address: string | null, abi: any[], signerOrProvider: RYTWallet | ethers.Provider | any);
|
|
88
|
+
/**
|
|
89
|
+
* Call a read-only contract method
|
|
90
|
+
*
|
|
91
|
+
* @param method - contract function name
|
|
92
|
+
* @param params - function arguments
|
|
93
|
+
* @returns result of contract call
|
|
94
|
+
*/
|
|
95
|
+
read(method: string, ...params: any[]): Promise<any>;
|
|
96
|
+
/**
|
|
97
|
+
* Call a state-changing contract method
|
|
98
|
+
*
|
|
99
|
+
* @param method - contract function name
|
|
100
|
+
* @param params - function arguments
|
|
101
|
+
* @returns transaction response
|
|
102
|
+
*/
|
|
103
|
+
write(method: string, ...params: any[]): Promise<any>;
|
|
104
|
+
/**
|
|
105
|
+
* Deploy a contract using CREATE opcode
|
|
106
|
+
*
|
|
107
|
+
* @param options - deployment options
|
|
108
|
+
* @returns updated contract instance
|
|
109
|
+
*/
|
|
110
|
+
deploy(options: DeployOptions): Promise<this>;
|
|
111
|
+
/**
|
|
112
|
+
* Deploy contract using CREATE2 factory
|
|
113
|
+
*
|
|
114
|
+
* @param options - CREATE2 deployment options
|
|
115
|
+
* @returns deployed contract address + receipt
|
|
116
|
+
*/
|
|
117
|
+
deployCreate2(options: Create2DeployOptions): Promise<{
|
|
118
|
+
receipt: any;
|
|
119
|
+
contractHash: string;
|
|
120
|
+
}>;
|
|
121
|
+
/**
|
|
122
|
+
* Deploy minimal proxy clone (EIP-1167)
|
|
123
|
+
*
|
|
124
|
+
* @param implementationAddress - logic contract address
|
|
125
|
+
* @returns transaction receipt
|
|
126
|
+
*/
|
|
127
|
+
deployClone(implementationAddress: string): Promise<ethers.TransactionReceipt | null>;
|
|
128
|
+
/**
|
|
129
|
+
* Deploy UUPS proxy contract
|
|
130
|
+
*
|
|
131
|
+
* @param options - UUPS deployment options
|
|
132
|
+
* @returns proxy-wrapped contract instance
|
|
133
|
+
*/
|
|
134
|
+
deployUUPS(options: UUPSDeployOptions): Promise<RYTContract>;
|
|
135
|
+
/**
|
|
136
|
+
* Deploy contract with Solidity libraries linked
|
|
137
|
+
*
|
|
138
|
+
* @param options - library deployment options
|
|
139
|
+
* @returns deployed contract instance
|
|
140
|
+
*/
|
|
141
|
+
deployWithLibraries(options: LibraryDeployOptions): Promise<this>;
|
|
142
|
+
}
|
package/dist/contract.js
ADDED
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
import { ethers } from "ethers";
|
|
2
|
+
import RYTWallet from "./wallet";
|
|
3
|
+
import ERC1967Proxy from "@openzeppelin/contracts/build/contracts/ERC1967Proxy.json";
|
|
4
|
+
/**
|
|
5
|
+
* -----------------------------
|
|
6
|
+
* Internal helper: Link libraries into bytecode
|
|
7
|
+
* -----------------------------
|
|
8
|
+
*
|
|
9
|
+
* @param bytecode - raw contract bytecode
|
|
10
|
+
* @param linkReferences - compiler link references
|
|
11
|
+
* @param libraries - deployed library addresses
|
|
12
|
+
* @returns linked bytecode string
|
|
13
|
+
*/
|
|
14
|
+
async function linkLibraries(bytecode, linkReferences, libraries) {
|
|
15
|
+
let linked = bytecode.startsWith("0x") ? bytecode.slice(2) : bytecode;
|
|
16
|
+
const patches = [];
|
|
17
|
+
for (const file of Object.keys(linkReferences)) {
|
|
18
|
+
for (const libName of Object.keys(linkReferences[file])) {
|
|
19
|
+
const address = libraries[libName];
|
|
20
|
+
if (!address) {
|
|
21
|
+
throw new Error(`Missing address for library ${libName}`);
|
|
22
|
+
}
|
|
23
|
+
for (const { start, length } of linkReferences[file][libName]) {
|
|
24
|
+
patches.push({
|
|
25
|
+
start,
|
|
26
|
+
length,
|
|
27
|
+
address: address.replace(/^0x/, "").toLowerCase(),
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
patches.sort((a, b) => b.start - a.start);
|
|
33
|
+
for (const { start, length, address } of patches) {
|
|
34
|
+
linked =
|
|
35
|
+
linked.slice(0, start * 2) +
|
|
36
|
+
address.padStart(length * 2, "0") +
|
|
37
|
+
linked.slice((start + length) * 2);
|
|
38
|
+
}
|
|
39
|
+
return linked;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* ----------------------------------------------------
|
|
43
|
+
* RYTContract - Core smart contract interaction layer
|
|
44
|
+
* ----------------------------------------------------
|
|
45
|
+
*
|
|
46
|
+
* Supports:
|
|
47
|
+
* - Read / Write contract calls
|
|
48
|
+
* - CREATE deployment
|
|
49
|
+
* - CREATE2 deployment
|
|
50
|
+
* - Minimal proxy (EIP-1167)
|
|
51
|
+
* - UUPS / ERC1967 proxy deployment
|
|
52
|
+
* - Library-linked deployment
|
|
53
|
+
*/
|
|
54
|
+
export default class RYTContract {
|
|
55
|
+
/**
|
|
56
|
+
* Create a new contract instance
|
|
57
|
+
*
|
|
58
|
+
* @param address - deployed contract address (optional)
|
|
59
|
+
* @param abi - contract ABI
|
|
60
|
+
* @param signerOrProvider - wallet or provider instance
|
|
61
|
+
*/
|
|
62
|
+
constructor(address, abi, signerOrProvider) {
|
|
63
|
+
this.wallet = signerOrProvider instanceof RYTWallet ? signerOrProvider : null;
|
|
64
|
+
const provider = signerOrProvider?.getProvider?.() || signerOrProvider;
|
|
65
|
+
this.contract = address
|
|
66
|
+
? new ethers.Contract(address, abi, this.wallet ? this.wallet["wallet"] : provider)
|
|
67
|
+
: null;
|
|
68
|
+
}
|
|
69
|
+
// ----------------------------------------------------
|
|
70
|
+
// Read & Write
|
|
71
|
+
// ----------------------------------------------------
|
|
72
|
+
/**
|
|
73
|
+
* Call a read-only contract method
|
|
74
|
+
*
|
|
75
|
+
* @param method - contract function name
|
|
76
|
+
* @param params - function arguments
|
|
77
|
+
* @returns result of contract call
|
|
78
|
+
*/
|
|
79
|
+
read(method, ...params) {
|
|
80
|
+
if (!this.contract)
|
|
81
|
+
throw new Error("Contract not initialized");
|
|
82
|
+
return this.contract[method](...params);
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Call a state-changing contract method
|
|
86
|
+
*
|
|
87
|
+
* @param method - contract function name
|
|
88
|
+
* @param params - function arguments
|
|
89
|
+
* @returns transaction response
|
|
90
|
+
*/
|
|
91
|
+
write(method, ...params) {
|
|
92
|
+
if (!this.contract)
|
|
93
|
+
throw new Error("Contract not initialized");
|
|
94
|
+
return this.contract[method](...params);
|
|
95
|
+
}
|
|
96
|
+
// ----------------------------------------------------
|
|
97
|
+
// CREATE Deployment
|
|
98
|
+
// ----------------------------------------------------
|
|
99
|
+
/**
|
|
100
|
+
* Deploy a contract using CREATE opcode
|
|
101
|
+
*
|
|
102
|
+
* @param options - deployment options
|
|
103
|
+
* @returns updated contract instance
|
|
104
|
+
*/
|
|
105
|
+
async deploy(options) {
|
|
106
|
+
if (!this.wallet)
|
|
107
|
+
throw new Error("Wallet required for deploy");
|
|
108
|
+
const factory = new ethers.ContractFactory(options.abi, options.bytecode, this.wallet["wallet"]);
|
|
109
|
+
const contract = await factory.deploy(...(options.args ?? []), {
|
|
110
|
+
value: options.value ?? 0,
|
|
111
|
+
});
|
|
112
|
+
await contract.waitForDeployment();
|
|
113
|
+
this.contract = contract;
|
|
114
|
+
return this;
|
|
115
|
+
}
|
|
116
|
+
// ----------------------------------------------------
|
|
117
|
+
// CREATE2 Deployment
|
|
118
|
+
// ----------------------------------------------------
|
|
119
|
+
/**
|
|
120
|
+
* Deploy contract using CREATE2 factory
|
|
121
|
+
*
|
|
122
|
+
* @param options - CREATE2 deployment options
|
|
123
|
+
* @returns deployed contract address + receipt
|
|
124
|
+
*/
|
|
125
|
+
async deployCreate2(options) {
|
|
126
|
+
if (!this.wallet)
|
|
127
|
+
throw new Error("Wallet required for deployCreate2");
|
|
128
|
+
const encodedArgs = options.args && options.args.length > 0
|
|
129
|
+
? new ethers.Interface(options.abi).encodeDeploy(options.args)
|
|
130
|
+
: "0x";
|
|
131
|
+
const creationCode = ethers.concat([
|
|
132
|
+
"0x" + options.bytecode,
|
|
133
|
+
encodedArgs,
|
|
134
|
+
]);
|
|
135
|
+
const factory = new ethers.Contract(options.factoryAddress, [
|
|
136
|
+
"function deploy(bytes32 salt, bytes code) external payable returns (address)",
|
|
137
|
+
], this.wallet["wallet"]);
|
|
138
|
+
const addr = ethers.getCreate2Address(options.factoryAddress, options.salt, ethers.keccak256(creationCode));
|
|
139
|
+
const tx = options.value && options.value > 0
|
|
140
|
+
? await factory.deploy(options.salt, creationCode, {
|
|
141
|
+
value: options.value,
|
|
142
|
+
})
|
|
143
|
+
: await factory.deploy(options.salt, creationCode);
|
|
144
|
+
return {
|
|
145
|
+
receipt: await tx.wait(),
|
|
146
|
+
contractHash: addr,
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
// ----------------------------------------------------
|
|
150
|
+
// Minimal Proxy (EIP-1167)
|
|
151
|
+
// ----------------------------------------------------
|
|
152
|
+
/**
|
|
153
|
+
* Deploy minimal proxy clone (EIP-1167)
|
|
154
|
+
*
|
|
155
|
+
* @param implementationAddress - logic contract address
|
|
156
|
+
* @returns transaction receipt
|
|
157
|
+
*/
|
|
158
|
+
async deployClone(implementationAddress) {
|
|
159
|
+
if (!this.wallet)
|
|
160
|
+
throw new Error("Wallet required for deployClone");
|
|
161
|
+
const bytecode = "0x3d602d80600a3d3981f3" +
|
|
162
|
+
"363d3d373d3d3d363d73" +
|
|
163
|
+
implementationAddress.slice(2) +
|
|
164
|
+
"5af43d82803e903d91602b57fd5bf3";
|
|
165
|
+
const tx = await this.wallet["wallet"].sendTransaction({
|
|
166
|
+
data: bytecode,
|
|
167
|
+
});
|
|
168
|
+
return await tx.wait();
|
|
169
|
+
}
|
|
170
|
+
// ----------------------------------------------------
|
|
171
|
+
// UUPS / ERC1967 Proxy
|
|
172
|
+
// ----------------------------------------------------
|
|
173
|
+
/**
|
|
174
|
+
* Deploy UUPS proxy contract
|
|
175
|
+
*
|
|
176
|
+
* @param options - UUPS deployment options
|
|
177
|
+
* @returns proxy-wrapped contract instance
|
|
178
|
+
*/
|
|
179
|
+
async deployUUPS(options) {
|
|
180
|
+
if (!this.wallet)
|
|
181
|
+
throw new Error("Wallet required for deployUUPS");
|
|
182
|
+
const implFactory = new ethers.ContractFactory(options.implementationAbi, options.implementationBytecode, this.wallet["wallet"]);
|
|
183
|
+
const impl = await implFactory.deploy();
|
|
184
|
+
await impl.waitForDeployment();
|
|
185
|
+
const implAddress = impl.target;
|
|
186
|
+
const proxyFactory = new ethers.ContractFactory(ERC1967Proxy.abi, ERC1967Proxy.bytecode, this.wallet["wallet"]);
|
|
187
|
+
const proxy = await proxyFactory.deploy(implAddress, options.initData ?? "0x");
|
|
188
|
+
await proxy.waitForDeployment();
|
|
189
|
+
return new RYTContract(proxy.target, options.implementationAbi, this.wallet);
|
|
190
|
+
}
|
|
191
|
+
// ----------------------------------------------------
|
|
192
|
+
// Library-linked deployment
|
|
193
|
+
// ----------------------------------------------------
|
|
194
|
+
/**
|
|
195
|
+
* Deploy contract with Solidity libraries linked
|
|
196
|
+
*
|
|
197
|
+
* @param options - library deployment options
|
|
198
|
+
* @returns deployed contract instance
|
|
199
|
+
*/
|
|
200
|
+
async deployWithLibraries(options) {
|
|
201
|
+
const linkedBytecode = await linkLibraries(options.bytecode, options.linkReferences, options.libraries ?? {});
|
|
202
|
+
return this.deploy({
|
|
203
|
+
abi: options.abi,
|
|
204
|
+
bytecode: linkedBytecode,
|
|
205
|
+
args: options.args ?? [],
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ------------------------------------------------------
|
|
3
|
+
* RYT SDK - Public Entry Point
|
|
4
|
+
* ------------------------------------------------------
|
|
5
|
+
*
|
|
6
|
+
* This file exposes the main SDK modules:
|
|
7
|
+
* - Provider (RPC layer)
|
|
8
|
+
* - Wallet (signing layer)
|
|
9
|
+
* - Contract (smart contract interaction layer)
|
|
10
|
+
*
|
|
11
|
+
* This is the ONLY file users should import from:
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```ts
|
|
15
|
+
* import { RYTProvider, RYTWallet, RYTContract } from "ryt-sdk";
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
/**
|
|
19
|
+
* Provider module for RPC interactions
|
|
20
|
+
*/
|
|
21
|
+
export { default as RYTProvider } from "./provider";
|
|
22
|
+
/**
|
|
23
|
+
* Wallet module for signing transactions
|
|
24
|
+
*/
|
|
25
|
+
export { default as RYTWallet } from "./wallet";
|
|
26
|
+
/**
|
|
27
|
+
* Contract module for smart contract interactions
|
|
28
|
+
*/
|
|
29
|
+
export { default as RYTContract } from "./contract";
|
|
30
|
+
/**
|
|
31
|
+
* ------------------------------------------------------
|
|
32
|
+
* Optional: Future unified SDK export (recommended)
|
|
33
|
+
* ------------------------------------------------------
|
|
34
|
+
*
|
|
35
|
+
* Uncomment when you want a single entry API:
|
|
36
|
+
*
|
|
37
|
+
* export { default as RYTClient } from "./client";
|
|
38
|
+
*/
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ------------------------------------------------------
|
|
3
|
+
* RYT SDK - Public Entry Point
|
|
4
|
+
* ------------------------------------------------------
|
|
5
|
+
*
|
|
6
|
+
* This file exposes the main SDK modules:
|
|
7
|
+
* - Provider (RPC layer)
|
|
8
|
+
* - Wallet (signing layer)
|
|
9
|
+
* - Contract (smart contract interaction layer)
|
|
10
|
+
*
|
|
11
|
+
* This is the ONLY file users should import from:
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```ts
|
|
15
|
+
* import { RYTProvider, RYTWallet, RYTContract } from "ryt-sdk";
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
/**
|
|
19
|
+
* Provider module for RPC interactions
|
|
20
|
+
*/
|
|
21
|
+
export { default as RYTProvider } from "./provider";
|
|
22
|
+
/**
|
|
23
|
+
* Wallet module for signing transactions
|
|
24
|
+
*/
|
|
25
|
+
export { default as RYTWallet } from "./wallet";
|
|
26
|
+
/**
|
|
27
|
+
* Contract module for smart contract interactions
|
|
28
|
+
*/
|
|
29
|
+
export { default as RYTContract } from "./contract";
|
|
30
|
+
/**
|
|
31
|
+
* ------------------------------------------------------
|
|
32
|
+
* Optional: Future unified SDK export (recommended)
|
|
33
|
+
* ------------------------------------------------------
|
|
34
|
+
*
|
|
35
|
+
* Uncomment when you want a single entry API:
|
|
36
|
+
*
|
|
37
|
+
* export { default as RYTClient } from "./client";
|
|
38
|
+
*/
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { ethers } from "ethers";
|
|
2
|
+
import type { SDKConfig } from "./config";
|
|
3
|
+
/**
|
|
4
|
+
* RYTProvider is a provider instance that connects to the blockchain and allows interaction with it.
|
|
5
|
+
*/
|
|
6
|
+
export default class RYTProvider {
|
|
7
|
+
private provider;
|
|
8
|
+
/**
|
|
9
|
+
* Create a new RYTProvider instance
|
|
10
|
+
*
|
|
11
|
+
* @param config - SDK configuration containing RPC URLs
|
|
12
|
+
* @param rpcUrl - Optional override RPC URL. If not provided, uses first config RPC URL
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```ts
|
|
16
|
+
* const provider = new RYTProvider(config);
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
constructor(config: SDKConfig, rpcUrl?: string);
|
|
20
|
+
/**
|
|
21
|
+
* Returns the provider instance
|
|
22
|
+
*
|
|
23
|
+
* @returns provider instance
|
|
24
|
+
*/
|
|
25
|
+
getProvider(): ethers.JsonRpcProvider;
|
|
26
|
+
/**
|
|
27
|
+
* Get the latest block number from the blockchain
|
|
28
|
+
*
|
|
29
|
+
* @returns Promise resolving to latest block number
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* ```ts
|
|
33
|
+
* const blockNumber = await provider.getBlockNumber();
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
getBlockNumber(): Promise<number>;
|
|
37
|
+
/**
|
|
38
|
+
* Get balance of a given address in wei
|
|
39
|
+
*
|
|
40
|
+
* @param address - Ethereum-style wallet address
|
|
41
|
+
* @returns Promise resolving to balance in wei (BigInt-compatible)
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* ```ts
|
|
45
|
+
* const balance = await provider.getBalance("0x123...");
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
48
|
+
getBalance(address: string): Promise<bigint>;
|
|
49
|
+
}
|
package/dist/provider.js
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { ethers } from "ethers";
|
|
2
|
+
/**
|
|
3
|
+
* RYTProvider is a provider instance that connects to the blockchain and allows interaction with it.
|
|
4
|
+
*/
|
|
5
|
+
export default class RYTProvider {
|
|
6
|
+
/**
|
|
7
|
+
* Create a new RYTProvider instance
|
|
8
|
+
*
|
|
9
|
+
* @param config - SDK configuration containing RPC URLs
|
|
10
|
+
* @param rpcUrl - Optional override RPC URL. If not provided, uses first config RPC URL
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```ts
|
|
14
|
+
* const provider = new RYTProvider(config);
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
constructor(config, rpcUrl) {
|
|
18
|
+
const rpc = rpcUrl ?? config.rpcUrls[0];
|
|
19
|
+
if (!rpc) {
|
|
20
|
+
throw new Error("No RPC URL provided in config or constructor");
|
|
21
|
+
}
|
|
22
|
+
this.provider = new ethers.JsonRpcProvider(rpc);
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Returns the provider instance
|
|
26
|
+
*
|
|
27
|
+
* @returns provider instance
|
|
28
|
+
*/
|
|
29
|
+
getProvider() {
|
|
30
|
+
return this.provider;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Get the latest block number from the blockchain
|
|
34
|
+
*
|
|
35
|
+
* @returns Promise resolving to latest block number
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* ```ts
|
|
39
|
+
* const blockNumber = await provider.getBlockNumber();
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
42
|
+
async getBlockNumber() {
|
|
43
|
+
return await this.provider.getBlockNumber();
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Get balance of a given address in wei
|
|
47
|
+
*
|
|
48
|
+
* @param address - Ethereum-style wallet address
|
|
49
|
+
* @returns Promise resolving to balance in wei (BigInt-compatible)
|
|
50
|
+
*
|
|
51
|
+
* @example
|
|
52
|
+
* ```ts
|
|
53
|
+
* const balance = await provider.getBalance("0x123...");
|
|
54
|
+
* ```
|
|
55
|
+
*/
|
|
56
|
+
async getBalance(address) {
|
|
57
|
+
if (!ethers.isAddress(address)) {
|
|
58
|
+
throw new Error(`Invalid address: ${address}`);
|
|
59
|
+
}
|
|
60
|
+
return await this.provider.getBalance(address);
|
|
61
|
+
}
|
|
62
|
+
}
|
package/dist/wallet.d.ts
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { ethers } from "ethers";
|
|
2
|
+
import type RYTProvider from "./provider";
|
|
3
|
+
/**
|
|
4
|
+
* Transaction request type
|
|
5
|
+
*/
|
|
6
|
+
export type TxRequest = ethers.TransactionRequest;
|
|
7
|
+
/**
|
|
8
|
+
* RYTWallet is a wallet instance that supports signing transactions and interacting with the blockchain.
|
|
9
|
+
*/
|
|
10
|
+
export default class RYTWallet {
|
|
11
|
+
private wallet;
|
|
12
|
+
/**
|
|
13
|
+
* Create a new RYTWallet instance
|
|
14
|
+
*
|
|
15
|
+
* @param privateKey - Ethereum private key (0x...)
|
|
16
|
+
* @param provider - Optional RYTProvider instance for network access
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```ts
|
|
20
|
+
* const wallet = new RYTWallet(PRIVATE_KEY, provider);
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
constructor(privateKey: string, provider?: RYTProvider);
|
|
24
|
+
/**
|
|
25
|
+
* Returns the wallet address
|
|
26
|
+
*
|
|
27
|
+
* @returns Wallet public address
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* ```ts
|
|
31
|
+
* const address = wallet.getAddress();
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
getAddress(): string;
|
|
35
|
+
/**
|
|
36
|
+
* Get wallet balance in wei
|
|
37
|
+
*
|
|
38
|
+
* @returns Promise resolving to balance (bigint)
|
|
39
|
+
*
|
|
40
|
+
* @throws Error if provider is not connected
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* ```ts
|
|
44
|
+
* const balance = await wallet.getBalance();
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
47
|
+
getBalance(): Promise<bigint>;
|
|
48
|
+
/**
|
|
49
|
+
* Send a signed transaction
|
|
50
|
+
*
|
|
51
|
+
* @param tx - Transaction object (to, value, data, etc.)
|
|
52
|
+
* @returns Promise resolving to transaction response
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
* ```ts
|
|
56
|
+
* await wallet.sendTransaction({
|
|
57
|
+
* to: "0xabc...",
|
|
58
|
+
* value: ethers.parseEther("0.01")
|
|
59
|
+
* });
|
|
60
|
+
* ```
|
|
61
|
+
*/
|
|
62
|
+
sendTransaction(tx: TxRequest): Promise<ethers.TransactionResponse>;
|
|
63
|
+
}
|
package/dist/wallet.js
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { ethers } from "ethers";
|
|
2
|
+
/**
|
|
3
|
+
* RYTWallet is a wallet instance that supports signing transactions and interacting with the blockchain.
|
|
4
|
+
*/
|
|
5
|
+
export default class RYTWallet {
|
|
6
|
+
/**
|
|
7
|
+
* Create a new RYTWallet instance
|
|
8
|
+
*
|
|
9
|
+
* @param privateKey - Ethereum private key (0x...)
|
|
10
|
+
* @param provider - Optional RYTProvider instance for network access
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```ts
|
|
14
|
+
* const wallet = new RYTWallet(PRIVATE_KEY, provider);
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
constructor(privateKey, provider) {
|
|
18
|
+
if (!privateKey) {
|
|
19
|
+
throw new Error("Private key is required");
|
|
20
|
+
}
|
|
21
|
+
// Ensure private key format is valid
|
|
22
|
+
if (!privateKey.startsWith("0x")) {
|
|
23
|
+
throw new Error("Invalid private key format: must start with 0x");
|
|
24
|
+
}
|
|
25
|
+
const ethersProvider = provider?.getProvider();
|
|
26
|
+
this.wallet = ethersProvider
|
|
27
|
+
? new ethers.Wallet(privateKey, ethersProvider)
|
|
28
|
+
: new ethers.Wallet(privateKey);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Returns the wallet address
|
|
32
|
+
*
|
|
33
|
+
* @returns Wallet public address
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```ts
|
|
37
|
+
* const address = wallet.getAddress();
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
getAddress() {
|
|
41
|
+
return this.wallet.address;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Get wallet balance in wei
|
|
45
|
+
*
|
|
46
|
+
* @returns Promise resolving to balance (bigint)
|
|
47
|
+
*
|
|
48
|
+
* @throws Error if provider is not connected
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* ```ts
|
|
52
|
+
* const balance = await wallet.getBalance();
|
|
53
|
+
* ```
|
|
54
|
+
*/
|
|
55
|
+
async getBalance() {
|
|
56
|
+
if (!this.wallet.provider) {
|
|
57
|
+
throw new Error("Provider not initialized. Attach a provider to fetch balance.");
|
|
58
|
+
}
|
|
59
|
+
return await this.wallet.provider.getBalance(this.wallet.address);
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Send a signed transaction
|
|
63
|
+
*
|
|
64
|
+
* @param tx - Transaction object (to, value, data, etc.)
|
|
65
|
+
* @returns Promise resolving to transaction response
|
|
66
|
+
*
|
|
67
|
+
* @example
|
|
68
|
+
* ```ts
|
|
69
|
+
* await wallet.sendTransaction({
|
|
70
|
+
* to: "0xabc...",
|
|
71
|
+
* value: ethers.parseEther("0.01")
|
|
72
|
+
* });
|
|
73
|
+
* ```
|
|
74
|
+
*/
|
|
75
|
+
async sendTransaction(tx) {
|
|
76
|
+
if (!this.wallet) {
|
|
77
|
+
throw new Error("Wallet not initialized");
|
|
78
|
+
}
|
|
79
|
+
return await this.wallet.sendTransaction(tx);
|
|
80
|
+
}
|
|
81
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "ryt-sdk",
|
|
3
|
+
"type": "module",
|
|
4
|
+
"version": "1.0.0",
|
|
5
|
+
"description": "RYT blockchain SDK for provider, wallet, and smart contract interactions",
|
|
6
|
+
"author": "Muhammad Hammad Mubeen",
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"main": "dist/index.js",
|
|
9
|
+
"types": "dist/index.d.ts",
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"import": "./dist/index.js",
|
|
13
|
+
"types": "./dist/index.d.ts"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"dist"
|
|
18
|
+
],
|
|
19
|
+
"sideEffects": false,
|
|
20
|
+
"engines": {
|
|
21
|
+
"node": ">=18"
|
|
22
|
+
},
|
|
23
|
+
"scripts": {
|
|
24
|
+
"build": "tsc",
|
|
25
|
+
"clean": "rimraf dist",
|
|
26
|
+
"prepublishOnly": "npm run clean && npm run build",
|
|
27
|
+
"test": "tsx tests/sdk.test.ts",
|
|
28
|
+
"contractsTest": "tsx tests/sdk.contracts.test.ts"
|
|
29
|
+
},
|
|
30
|
+
"keywords": [
|
|
31
|
+
"blockchain",
|
|
32
|
+
"sdk",
|
|
33
|
+
"ryt",
|
|
34
|
+
"ethereum",
|
|
35
|
+
"web3",
|
|
36
|
+
"ethers-v6",
|
|
37
|
+
"smart-contracts",
|
|
38
|
+
"create2",
|
|
39
|
+
"uups",
|
|
40
|
+
"erc20",
|
|
41
|
+
"erc721"
|
|
42
|
+
],
|
|
43
|
+
"dependencies": {
|
|
44
|
+
"dotenv": "^17.2.3",
|
|
45
|
+
"ethers": "^6.8.0"
|
|
46
|
+
},
|
|
47
|
+
"devDependencies": {
|
|
48
|
+
"@openzeppelin/contracts": "^5.4.0",
|
|
49
|
+
"@openzeppelin/contracts-upgradeable": "^5.4.0",
|
|
50
|
+
"@types/node": "^20.0.0",
|
|
51
|
+
"eslint": "^8.0.0",
|
|
52
|
+
"prettier": "^2.8.0",
|
|
53
|
+
"rimraf": "^6.0.0",
|
|
54
|
+
"ts-node": "^10.9.0",
|
|
55
|
+
"tsx": "^4.21.0",
|
|
56
|
+
"typescript": "^5.0.0"
|
|
57
|
+
},
|
|
58
|
+
"publishConfig": {
|
|
59
|
+
"access": "public"
|
|
60
|
+
}
|
|
61
|
+
}
|