@dynamic-labs/solana-core 4.0.0-alpha.26 → 4.0.0-alpha.28
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/CHANGELOG.md +33 -0
- package/package.cjs +1 -1
- package/package.js +1 -1
- package/package.json +7 -7
- package/src/connector/SolanaWalletConnector.cjs +4 -3
- package/src/connector/SolanaWalletConnector.d.ts +3 -1
- package/src/connector/SolanaWalletConnector.js +4 -3
- package/src/rpc/RpcProviderSolana/RpcProviderSolana.cjs +2 -2
- package/src/rpc/RpcProviderSolana/RpcProviderSolana.d.ts +2 -2
- package/src/rpc/RpcProviderSolana/RpcProviderSolana.js +2 -2
- package/src/utils/SolanaUiTransaction/SolanaUiTransaction.cjs +58 -37
- package/src/utils/SolanaUiTransaction/SolanaUiTransaction.d.ts +8 -8
- package/src/utils/SolanaUiTransaction/SolanaUiTransaction.js +58 -37
package/CHANGELOG.md
CHANGED
|
@@ -1,4 +1,37 @@
|
|
|
1
1
|
|
|
2
|
+
## [4.0.0-alpha.28](https://github.com/dynamic-labs/dynamic-auth/compare/v4.0.0-alpha.27...v4.0.0-alpha.28) (2024-11-07)
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
### ⚠ BREAKING CHANGES
|
|
6
|
+
|
|
7
|
+
* upgrade to starknet v6
|
|
8
|
+
See this guide for more details: https://starknetjs.com/docs/guides/migrate/
|
|
9
|
+
There are no code changes required on the Dynamic SDK side, however if you have installed the `starknet` package, you will need to upgrade to >= v6.11.0.
|
|
10
|
+
|
|
11
|
+
### Features
|
|
12
|
+
|
|
13
|
+
* new transaction modal and ui for sign/signAll ([#7296](https://github.com/dynamic-labs/dynamic-auth/issues/7296)) ([05a8af1](https://github.com/dynamic-labs/dynamic-auth/commit/05a8af1eb772b2b8087ed96a54caf4b6ae8b79d2)), closes [#7297](https://github.com/dynamic-labs/dynamic-auth/issues/7297) [#7298](https://github.com/dynamic-labs/dynamic-auth/issues/7298)
|
|
14
|
+
* upgrade to starknet v6 ([#7189](https://github.com/dynamic-labs/dynamic-auth/issues/7189)) ([2a6e24e](https://github.com/dynamic-labs/dynamic-auth/commit/2a6e24e4178fcee671b381c28f6a681f4ce52c62))
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
### Bug Fixes
|
|
18
|
+
|
|
19
|
+
* transaction confirmation modal popup ([#7368](https://github.com/dynamic-labs/dynamic-auth/issues/7368)) ([3c48658](https://github.com/dynamic-labs/dynamic-auth/commit/3c48658a62874d908bba8f06fb092ff5983ede16))
|
|
20
|
+
|
|
21
|
+
## [4.0.0-alpha.27](https://github.com/dynamic-labs/dynamic-auth/compare/v4.0.0-alpha.26...v4.0.0-alpha.27) (2024-11-06)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
### Features
|
|
25
|
+
|
|
26
|
+
* allows adding connection configuration for solana connectors ([#7354](https://github.com/dynamic-labs/dynamic-auth/issues/7354)) ([01e35ee](https://github.com/dynamic-labs/dynamic-auth/commit/01e35ee5bfe4605df48e4188a753111efe483048))
|
|
27
|
+
* allows passing solana connection config to dynamic client ([#7357](https://github.com/dynamic-labs/dynamic-auth/issues/7357)) ([6da14ce](https://github.com/dynamic-labs/dynamic-auth/commit/6da14ceb481147aea31d192fe268be43a8af80e9))
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
### Bug Fixes
|
|
31
|
+
|
|
32
|
+
* check legacy vs eip1599 tx in global connectivity ([#7341](https://github.com/dynamic-labs/dynamic-auth/issues/7341)) ([b223ea7](https://github.com/dynamic-labs/dynamic-auth/commit/b223ea7a5ed5637e11da1040c631c48bc23ba76d))
|
|
33
|
+
* global connectivity multiple transactions in a row ([#7342](https://github.com/dynamic-labs/dynamic-auth/issues/7342)) ([d13c1af](https://github.com/dynamic-labs/dynamic-auth/commit/d13c1afec6b3680961621d8317f55549b3ed428f))
|
|
34
|
+
|
|
2
35
|
## [4.0.0-alpha.26](https://github.com/dynamic-labs/dynamic-auth/compare/v4.0.0-alpha.25...v4.0.0-alpha.26) (2024-11-04)
|
|
3
36
|
|
|
4
37
|
## [4.0.0-alpha.25](https://github.com/dynamic-labs/dynamic-auth/compare/v4.0.0-alpha.24...v4.0.0-alpha.25) (2024-11-01)
|
package/package.cjs
CHANGED
package/package.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dynamic-labs/solana-core",
|
|
3
|
-
"version": "4.0.0-alpha.
|
|
3
|
+
"version": "4.0.0-alpha.28",
|
|
4
4
|
"description": "Core package for utilities and types for solana",
|
|
5
5
|
"author": "Dynamic Labs, Inc.",
|
|
6
6
|
"license": "MIT",
|
|
@@ -23,12 +23,12 @@
|
|
|
23
23
|
"@solana/spl-token": "0.4.6"
|
|
24
24
|
},
|
|
25
25
|
"peerDependencies": {
|
|
26
|
-
"@dynamic-labs/assert-package-version": "4.0.0-alpha.
|
|
27
|
-
"@dynamic-labs/rpc-providers": "4.0.0-alpha.
|
|
28
|
-
"@dynamic-labs/types": "4.0.0-alpha.
|
|
29
|
-
"@dynamic-labs/utils": "4.0.0-alpha.
|
|
30
|
-
"@dynamic-labs/wallet-book": "4.0.0-alpha.
|
|
31
|
-
"@dynamic-labs/wallet-connector-core": "4.0.0-alpha.
|
|
26
|
+
"@dynamic-labs/assert-package-version": "4.0.0-alpha.28",
|
|
27
|
+
"@dynamic-labs/rpc-providers": "4.0.0-alpha.28",
|
|
28
|
+
"@dynamic-labs/types": "4.0.0-alpha.28",
|
|
29
|
+
"@dynamic-labs/utils": "4.0.0-alpha.28",
|
|
30
|
+
"@dynamic-labs/wallet-book": "4.0.0-alpha.28",
|
|
31
|
+
"@dynamic-labs/wallet-connector-core": "4.0.0-alpha.28",
|
|
32
32
|
"eventemitter3": "5.0.1"
|
|
33
33
|
}
|
|
34
34
|
}
|
|
@@ -24,7 +24,8 @@ class SolanaWalletConnector extends walletConnectorCore.WalletConnectorBase {
|
|
|
24
24
|
this.connectedChain = 'SOL';
|
|
25
25
|
this.solNetworks = opts.solNetworks;
|
|
26
26
|
this.chainRpcProviders = opts.chainRpcProviders;
|
|
27
|
-
|
|
27
|
+
this.connectionConfig = opts.connectionConfig;
|
|
28
|
+
(_a = this.chainRpcProviders) === null || _a === void 0 ? void 0 : _a.registerSolanaProviders(this.connectionConfig);
|
|
28
29
|
}
|
|
29
30
|
getNetwork() {
|
|
30
31
|
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
@@ -55,13 +56,13 @@ class SolanaWalletConnector extends walletConnectorCore.WalletConnectorBase {
|
|
|
55
56
|
});
|
|
56
57
|
}
|
|
57
58
|
getWalletClient() {
|
|
58
|
-
var _a;
|
|
59
|
+
var _a, _b;
|
|
59
60
|
const [network] = this.solNetworks;
|
|
60
61
|
if (!network) {
|
|
61
62
|
throw new utils.DynamicError('No enabled networks');
|
|
62
63
|
}
|
|
63
64
|
const rpcUrl = ((_a = network.privateCustomerRpcUrls) === null || _a === void 0 ? void 0 : _a[0]) || network.rpcUrls[0];
|
|
64
|
-
return new web3_js.Connection(rpcUrl, 'confirmed');
|
|
65
|
+
return new web3_js.Connection(rpcUrl, (_b = this.connectionConfig) !== null && _b !== void 0 ? _b : 'confirmed');
|
|
65
66
|
}
|
|
66
67
|
getPublicClient() {
|
|
67
68
|
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Connection } from '@solana/web3.js';
|
|
1
|
+
import { Connection, ConnectionConfig } from '@solana/web3.js';
|
|
2
2
|
import { Chain, IHardwareWalletConnector, WalletConnectorBase, WalletMetadata } from '@dynamic-labs/wallet-connector-core';
|
|
3
3
|
import { GenericNetwork } from '@dynamic-labs/types';
|
|
4
4
|
import { WalletBookSchema } from '@dynamic-labs/wallet-book';
|
|
@@ -11,6 +11,7 @@ export type SolanaWalletConnectorOpts = {
|
|
|
11
11
|
solNetworks: GenericNetwork[];
|
|
12
12
|
walletBook: WalletBookSchema;
|
|
13
13
|
metadata?: WalletMetadata;
|
|
14
|
+
connectionConfig?: ConnectionConfig;
|
|
14
15
|
};
|
|
15
16
|
export declare abstract class SolanaWalletConnector extends WalletConnectorBase<typeof SolanaWallet> implements IHardwareWalletConnector {
|
|
16
17
|
isHardwareWalletEnabled: boolean;
|
|
@@ -19,6 +20,7 @@ export declare abstract class SolanaWalletConnector extends WalletConnectorBase<
|
|
|
19
20
|
ChainWallet: typeof SolanaWallet;
|
|
20
21
|
supportedChains: Chain[];
|
|
21
22
|
connectedChain: Chain;
|
|
23
|
+
protected connectionConfig: ConnectionConfig | undefined;
|
|
22
24
|
constructor(opts: SolanaWalletConnectorOpts);
|
|
23
25
|
getNetwork(): Promise<string>;
|
|
24
26
|
endSession(): Promise<void>;
|
|
@@ -20,7 +20,8 @@ class SolanaWalletConnector extends WalletConnectorBase {
|
|
|
20
20
|
this.connectedChain = 'SOL';
|
|
21
21
|
this.solNetworks = opts.solNetworks;
|
|
22
22
|
this.chainRpcProviders = opts.chainRpcProviders;
|
|
23
|
-
|
|
23
|
+
this.connectionConfig = opts.connectionConfig;
|
|
24
|
+
(_a = this.chainRpcProviders) === null || _a === void 0 ? void 0 : _a.registerSolanaProviders(this.connectionConfig);
|
|
24
25
|
}
|
|
25
26
|
getNetwork() {
|
|
26
27
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -51,13 +52,13 @@ class SolanaWalletConnector extends WalletConnectorBase {
|
|
|
51
52
|
});
|
|
52
53
|
}
|
|
53
54
|
getWalletClient() {
|
|
54
|
-
var _a;
|
|
55
|
+
var _a, _b;
|
|
55
56
|
const [network] = this.solNetworks;
|
|
56
57
|
if (!network) {
|
|
57
58
|
throw new DynamicError('No enabled networks');
|
|
58
59
|
}
|
|
59
60
|
const rpcUrl = ((_a = network.privateCustomerRpcUrls) === null || _a === void 0 ? void 0 : _a[0]) || network.rpcUrls[0];
|
|
60
|
-
return new Connection(rpcUrl, 'confirmed');
|
|
61
|
+
return new Connection(rpcUrl, (_b = this.connectionConfig) !== null && _b !== void 0 ? _b : 'confirmed');
|
|
61
62
|
}
|
|
62
63
|
getPublicClient() {
|
|
63
64
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -9,14 +9,14 @@ rpcProviders.ChainRpcProviders.getSolanaProviderByChainId = (rpcProviders, chain
|
|
|
9
9
|
const provider = (_a = rpcProviders['solana']) === null || _a === void 0 ? void 0 : _a.find((rpcProvider) => rpcProvider.chainId === chainId);
|
|
10
10
|
return provider;
|
|
11
11
|
};
|
|
12
|
-
rpcProviders.ChainRpcProviders.registerSolanaProviders = () => {
|
|
12
|
+
rpcProviders.ChainRpcProviders.registerSolanaProviders = (connectionConfig) => {
|
|
13
13
|
rpcProviders.ChainRpcProviders.registerChainProviders(rpcProviders.ProviderChain.SOLANA, (config) => {
|
|
14
14
|
const rpcProviders = {};
|
|
15
15
|
if (config === null || config === void 0 ? void 0 : config.solana) {
|
|
16
16
|
rpcProviders.solana = config.solana.map((network) => {
|
|
17
17
|
var _a;
|
|
18
18
|
const rpcUrl = ((_a = network.privateCustomerRpcUrls) === null || _a === void 0 ? void 0 : _a[0]) || network.rpcUrls[0];
|
|
19
|
-
const provider = new web3_js.Connection(rpcUrl);
|
|
19
|
+
const provider = new web3_js.Connection(rpcUrl, connectionConfig);
|
|
20
20
|
return {
|
|
21
21
|
chainId: network.chainId.toString(),
|
|
22
22
|
chainName: network.name,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Connection } from '@solana/web3.js';
|
|
1
|
+
import { Connection, ConnectionConfig } from '@solana/web3.js';
|
|
2
2
|
import { RpcProviders } from '@dynamic-labs/rpc-providers';
|
|
3
3
|
type ISolanaRpcProvider = {
|
|
4
4
|
chainId: string;
|
|
@@ -12,7 +12,7 @@ declare module '@dynamic-labs/rpc-providers' {
|
|
|
12
12
|
}
|
|
13
13
|
interface IChainRpcProviders {
|
|
14
14
|
getSolanaProviderByChainId(rpcProviders: RpcProviders, chainId: string): SolanaRpcProvider | undefined;
|
|
15
|
-
registerSolanaProviders(): void;
|
|
15
|
+
registerSolanaProviders(connectionConfig?: ConnectionConfig): void;
|
|
16
16
|
}
|
|
17
17
|
}
|
|
18
18
|
export {};
|
|
@@ -7,14 +7,14 @@ ChainRpcProviders.getSolanaProviderByChainId = (rpcProviders, chainId) => {
|
|
|
7
7
|
const provider = (_a = rpcProviders['solana']) === null || _a === void 0 ? void 0 : _a.find((rpcProvider) => rpcProvider.chainId === chainId);
|
|
8
8
|
return provider;
|
|
9
9
|
};
|
|
10
|
-
ChainRpcProviders.registerSolanaProviders = () => {
|
|
10
|
+
ChainRpcProviders.registerSolanaProviders = (connectionConfig) => {
|
|
11
11
|
ChainRpcProviders.registerChainProviders(ProviderChain.SOLANA, (config) => {
|
|
12
12
|
const rpcProviders = {};
|
|
13
13
|
if (config === null || config === void 0 ? void 0 : config.solana) {
|
|
14
14
|
rpcProviders.solana = config.solana.map((network) => {
|
|
15
15
|
var _a;
|
|
16
16
|
const rpcUrl = ((_a = network.privateCustomerRpcUrls) === null || _a === void 0 ? void 0 : _a[0]) || network.rpcUrls[0];
|
|
17
|
-
const provider = new Connection(rpcUrl);
|
|
17
|
+
const provider = new Connection(rpcUrl, connectionConfig);
|
|
18
18
|
return {
|
|
19
19
|
chainId: network.chainId.toString(),
|
|
20
20
|
chainName: network.name,
|
|
@@ -10,16 +10,64 @@ var utils = require('@dynamic-labs/utils');
|
|
|
10
10
|
|
|
11
11
|
const LAMPORTS_PER_SOL = 1000000000;
|
|
12
12
|
class SolanaUiTransaction {
|
|
13
|
-
constructor({ onSubmit, from, connection,
|
|
13
|
+
constructor({ onSubmit, from, connection, multipleTransactions, }) {
|
|
14
14
|
this.chain = 'SOL';
|
|
15
15
|
this.data = undefined;
|
|
16
16
|
this.fee = { gas: undefined };
|
|
17
|
-
this.feeDeducted = false;
|
|
18
17
|
this.formatNonNativeToken = (value, decimals) => (Number(value) / Number(Math.pow(10, decimals))).toString();
|
|
19
18
|
this.from = from;
|
|
20
19
|
this.onSubmit = onSubmit;
|
|
21
20
|
this.connection = connection;
|
|
22
|
-
this.
|
|
21
|
+
this.multipleTransactions = multipleTransactions;
|
|
22
|
+
}
|
|
23
|
+
fetchFee() {
|
|
24
|
+
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
25
|
+
if (this.fee.gas)
|
|
26
|
+
return;
|
|
27
|
+
let transactions = this.multipleTransactions;
|
|
28
|
+
// for send balance flow, create the transaction and then estimate it
|
|
29
|
+
if (!transactions) {
|
|
30
|
+
const tx = yield this.createTransactionSafe();
|
|
31
|
+
if (!tx)
|
|
32
|
+
return;
|
|
33
|
+
transactions = tx instanceof Array ? tx : [tx];
|
|
34
|
+
}
|
|
35
|
+
const compiledMessages = transactions.map((tx) => 'version' in tx ? tx.message : tx.compileMessage());
|
|
36
|
+
if (compiledMessages.some((msg) => !msg)) {
|
|
37
|
+
throw new Error('Invalid transaction');
|
|
38
|
+
}
|
|
39
|
+
const getFeeWithRetry = (message) => _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
40
|
+
let res = yield this.connection.getFeeForMessage(message);
|
|
41
|
+
let retryCount = 0;
|
|
42
|
+
while (res.value === null && retryCount < 5) {
|
|
43
|
+
res = yield this.connection.getFeeForMessage(message);
|
|
44
|
+
retryCount++;
|
|
45
|
+
}
|
|
46
|
+
return res.value ? BigInt(res.value) : BigInt(0);
|
|
47
|
+
});
|
|
48
|
+
const fees = yield Promise.all(compiledMessages.map((message) => getFeeWithRetry(message)));
|
|
49
|
+
this.fee.gas = fees.reduce((acc, fee) => acc + fee, BigInt(0));
|
|
50
|
+
if (this.fee.gas === BigInt(0)) {
|
|
51
|
+
this.fee.gas = undefined;
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
// if one of the transactions is not sponsored,
|
|
56
|
+
// then the simulation will have a solana transfer in it if it was successful
|
|
57
|
+
isGasSponsored() {
|
|
58
|
+
var _a;
|
|
59
|
+
if (!((_a = this.multipleTransactions) === null || _a === void 0 ? void 0 : _a.length))
|
|
60
|
+
return false;
|
|
61
|
+
return this.multipleTransactions.every((tx) => {
|
|
62
|
+
var _a;
|
|
63
|
+
if ('version' in tx) {
|
|
64
|
+
return this.from !== tx.message.staticAccountKeys[0].toBase58();
|
|
65
|
+
}
|
|
66
|
+
if ('feePayer' in tx) {
|
|
67
|
+
return this.from !== ((_a = tx.feePayer) === null || _a === void 0 ? void 0 : _a.toBase58());
|
|
68
|
+
}
|
|
69
|
+
return false;
|
|
70
|
+
});
|
|
23
71
|
}
|
|
24
72
|
parse(input) {
|
|
25
73
|
const floatValue = parseFloat(input);
|
|
@@ -40,7 +88,11 @@ class SolanaUiTransaction {
|
|
|
40
88
|
}
|
|
41
89
|
submit() {
|
|
42
90
|
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
43
|
-
|
|
91
|
+
if (this.multipleTransactions) {
|
|
92
|
+
return this.onSubmit();
|
|
93
|
+
}
|
|
94
|
+
// send balance modal transactions
|
|
95
|
+
const sendTransaction = (yield this.createTransaction());
|
|
44
96
|
return this.onSubmit(sendTransaction);
|
|
45
97
|
});
|
|
46
98
|
}
|
|
@@ -57,37 +109,6 @@ class SolanaUiTransaction {
|
|
|
57
109
|
}
|
|
58
110
|
return /^[1-9A-HJ-NP-Za-km-z]{32,44}$/.test(address);
|
|
59
111
|
}
|
|
60
|
-
fetchFee() {
|
|
61
|
-
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
62
|
-
if (this.fee.gas)
|
|
63
|
-
return;
|
|
64
|
-
const transaction = yield this.createTransactionSafe();
|
|
65
|
-
if (!transaction) {
|
|
66
|
-
return;
|
|
67
|
-
}
|
|
68
|
-
let compiledMessage;
|
|
69
|
-
if ('version' in transaction) {
|
|
70
|
-
compiledMessage = transaction.message;
|
|
71
|
-
}
|
|
72
|
-
else {
|
|
73
|
-
compiledMessage = transaction.compileMessage();
|
|
74
|
-
}
|
|
75
|
-
if (!compiledMessage) {
|
|
76
|
-
throw new Error('Invalid transaction');
|
|
77
|
-
}
|
|
78
|
-
let res = yield this.connection.getFeeForMessage(compiledMessage);
|
|
79
|
-
let retryCount = 0;
|
|
80
|
-
while (res.value === null && retryCount < 5) {
|
|
81
|
-
res = yield this.connection.getFeeForMessage(compiledMessage);
|
|
82
|
-
retryCount++;
|
|
83
|
-
}
|
|
84
|
-
this.fee.gas = res.value ? BigInt(res.value) : undefined;
|
|
85
|
-
if (!this.feeDeducted && this.fee.gas && this.value) {
|
|
86
|
-
this.value = this.value - this.fee.gas;
|
|
87
|
-
this.feeDeducted = true;
|
|
88
|
-
}
|
|
89
|
-
});
|
|
90
|
-
}
|
|
91
112
|
createTransaction() {
|
|
92
113
|
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
93
114
|
var _a;
|
|
@@ -95,8 +116,8 @@ class SolanaUiTransaction {
|
|
|
95
116
|
if (!to) {
|
|
96
117
|
throw new Error('Destination is required');
|
|
97
118
|
}
|
|
98
|
-
if (this.
|
|
99
|
-
return this.
|
|
119
|
+
if (this.multipleTransactions) {
|
|
120
|
+
return this.multipleTransactions;
|
|
100
121
|
}
|
|
101
122
|
const sendTransaction = new web3_js.Transaction();
|
|
102
123
|
const fromPubkey = new web3_js.PublicKey(this.from);
|
|
@@ -4,11 +4,10 @@ export declare const LAMPORTS_PER_SOL = 1000000000;
|
|
|
4
4
|
type SolanaUiTransactionProps = {
|
|
5
5
|
from: string;
|
|
6
6
|
connection: Connection;
|
|
7
|
-
onSubmit: (transaction
|
|
8
|
-
|
|
7
|
+
onSubmit: (transaction?: Transaction | VersionedTransaction) => Promise<any>;
|
|
8
|
+
multipleTransactions?: (Transaction | VersionedTransaction)[];
|
|
9
9
|
};
|
|
10
10
|
export declare class SolanaUiTransaction implements IUITransaction {
|
|
11
|
-
notEnoughFundsError: boolean | undefined;
|
|
12
11
|
to: string | undefined;
|
|
13
12
|
from: string;
|
|
14
13
|
value: bigint | undefined;
|
|
@@ -18,22 +17,23 @@ export declare class SolanaUiTransaction implements IUITransaction {
|
|
|
18
17
|
fee: {
|
|
19
18
|
gas: bigint | undefined;
|
|
20
19
|
};
|
|
21
|
-
|
|
22
|
-
feeDeducted: boolean;
|
|
20
|
+
multipleTransactions?: (Transaction | VersionedTransaction)[];
|
|
23
21
|
nonNativeAddress?: string;
|
|
24
22
|
nonNativeDecimal?: number;
|
|
25
23
|
nonNativeValue?: bigint;
|
|
26
24
|
private onSubmit;
|
|
27
25
|
private connection;
|
|
28
|
-
constructor({ onSubmit, from, connection,
|
|
26
|
+
constructor({ onSubmit, from, connection, multipleTransactions, }: SolanaUiTransactionProps);
|
|
27
|
+
nativePrice?: number | undefined;
|
|
28
|
+
fetchFee(): Promise<void>;
|
|
29
|
+
isGasSponsored(): boolean;
|
|
29
30
|
parse(input: string): bigint;
|
|
30
31
|
parseNonNativeToken(input: string, decimals: number): bigint;
|
|
31
32
|
formatNonNativeToken: (value: bigint, decimals: number) => string;
|
|
32
33
|
format(value: bigint, { precision }?: IUITransactionFormatOptions): string;
|
|
33
|
-
submit(): Promise<
|
|
34
|
+
submit(): Promise<any>;
|
|
34
35
|
getBalance(): Promise<bigint>;
|
|
35
36
|
validateAddressFormat(address: string): boolean;
|
|
36
|
-
fetchFee(): Promise<void>;
|
|
37
37
|
private createTransaction;
|
|
38
38
|
private createTransactionSafe;
|
|
39
39
|
}
|
|
@@ -6,16 +6,64 @@ import { formatNumberText } from '@dynamic-labs/utils';
|
|
|
6
6
|
|
|
7
7
|
const LAMPORTS_PER_SOL = 1000000000;
|
|
8
8
|
class SolanaUiTransaction {
|
|
9
|
-
constructor({ onSubmit, from, connection,
|
|
9
|
+
constructor({ onSubmit, from, connection, multipleTransactions, }) {
|
|
10
10
|
this.chain = 'SOL';
|
|
11
11
|
this.data = undefined;
|
|
12
12
|
this.fee = { gas: undefined };
|
|
13
|
-
this.feeDeducted = false;
|
|
14
13
|
this.formatNonNativeToken = (value, decimals) => (Number(value) / Number(Math.pow(10, decimals))).toString();
|
|
15
14
|
this.from = from;
|
|
16
15
|
this.onSubmit = onSubmit;
|
|
17
16
|
this.connection = connection;
|
|
18
|
-
this.
|
|
17
|
+
this.multipleTransactions = multipleTransactions;
|
|
18
|
+
}
|
|
19
|
+
fetchFee() {
|
|
20
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
21
|
+
if (this.fee.gas)
|
|
22
|
+
return;
|
|
23
|
+
let transactions = this.multipleTransactions;
|
|
24
|
+
// for send balance flow, create the transaction and then estimate it
|
|
25
|
+
if (!transactions) {
|
|
26
|
+
const tx = yield this.createTransactionSafe();
|
|
27
|
+
if (!tx)
|
|
28
|
+
return;
|
|
29
|
+
transactions = tx instanceof Array ? tx : [tx];
|
|
30
|
+
}
|
|
31
|
+
const compiledMessages = transactions.map((tx) => 'version' in tx ? tx.message : tx.compileMessage());
|
|
32
|
+
if (compiledMessages.some((msg) => !msg)) {
|
|
33
|
+
throw new Error('Invalid transaction');
|
|
34
|
+
}
|
|
35
|
+
const getFeeWithRetry = (message) => __awaiter(this, void 0, void 0, function* () {
|
|
36
|
+
let res = yield this.connection.getFeeForMessage(message);
|
|
37
|
+
let retryCount = 0;
|
|
38
|
+
while (res.value === null && retryCount < 5) {
|
|
39
|
+
res = yield this.connection.getFeeForMessage(message);
|
|
40
|
+
retryCount++;
|
|
41
|
+
}
|
|
42
|
+
return res.value ? BigInt(res.value) : BigInt(0);
|
|
43
|
+
});
|
|
44
|
+
const fees = yield Promise.all(compiledMessages.map((message) => getFeeWithRetry(message)));
|
|
45
|
+
this.fee.gas = fees.reduce((acc, fee) => acc + fee, BigInt(0));
|
|
46
|
+
if (this.fee.gas === BigInt(0)) {
|
|
47
|
+
this.fee.gas = undefined;
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
// if one of the transactions is not sponsored,
|
|
52
|
+
// then the simulation will have a solana transfer in it if it was successful
|
|
53
|
+
isGasSponsored() {
|
|
54
|
+
var _a;
|
|
55
|
+
if (!((_a = this.multipleTransactions) === null || _a === void 0 ? void 0 : _a.length))
|
|
56
|
+
return false;
|
|
57
|
+
return this.multipleTransactions.every((tx) => {
|
|
58
|
+
var _a;
|
|
59
|
+
if ('version' in tx) {
|
|
60
|
+
return this.from !== tx.message.staticAccountKeys[0].toBase58();
|
|
61
|
+
}
|
|
62
|
+
if ('feePayer' in tx) {
|
|
63
|
+
return this.from !== ((_a = tx.feePayer) === null || _a === void 0 ? void 0 : _a.toBase58());
|
|
64
|
+
}
|
|
65
|
+
return false;
|
|
66
|
+
});
|
|
19
67
|
}
|
|
20
68
|
parse(input) {
|
|
21
69
|
const floatValue = parseFloat(input);
|
|
@@ -36,7 +84,11 @@ class SolanaUiTransaction {
|
|
|
36
84
|
}
|
|
37
85
|
submit() {
|
|
38
86
|
return __awaiter(this, void 0, void 0, function* () {
|
|
39
|
-
|
|
87
|
+
if (this.multipleTransactions) {
|
|
88
|
+
return this.onSubmit();
|
|
89
|
+
}
|
|
90
|
+
// send balance modal transactions
|
|
91
|
+
const sendTransaction = (yield this.createTransaction());
|
|
40
92
|
return this.onSubmit(sendTransaction);
|
|
41
93
|
});
|
|
42
94
|
}
|
|
@@ -53,37 +105,6 @@ class SolanaUiTransaction {
|
|
|
53
105
|
}
|
|
54
106
|
return /^[1-9A-HJ-NP-Za-km-z]{32,44}$/.test(address);
|
|
55
107
|
}
|
|
56
|
-
fetchFee() {
|
|
57
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
58
|
-
if (this.fee.gas)
|
|
59
|
-
return;
|
|
60
|
-
const transaction = yield this.createTransactionSafe();
|
|
61
|
-
if (!transaction) {
|
|
62
|
-
return;
|
|
63
|
-
}
|
|
64
|
-
let compiledMessage;
|
|
65
|
-
if ('version' in transaction) {
|
|
66
|
-
compiledMessage = transaction.message;
|
|
67
|
-
}
|
|
68
|
-
else {
|
|
69
|
-
compiledMessage = transaction.compileMessage();
|
|
70
|
-
}
|
|
71
|
-
if (!compiledMessage) {
|
|
72
|
-
throw new Error('Invalid transaction');
|
|
73
|
-
}
|
|
74
|
-
let res = yield this.connection.getFeeForMessage(compiledMessage);
|
|
75
|
-
let retryCount = 0;
|
|
76
|
-
while (res.value === null && retryCount < 5) {
|
|
77
|
-
res = yield this.connection.getFeeForMessage(compiledMessage);
|
|
78
|
-
retryCount++;
|
|
79
|
-
}
|
|
80
|
-
this.fee.gas = res.value ? BigInt(res.value) : undefined;
|
|
81
|
-
if (!this.feeDeducted && this.fee.gas && this.value) {
|
|
82
|
-
this.value = this.value - this.fee.gas;
|
|
83
|
-
this.feeDeducted = true;
|
|
84
|
-
}
|
|
85
|
-
});
|
|
86
|
-
}
|
|
87
108
|
createTransaction() {
|
|
88
109
|
return __awaiter(this, void 0, void 0, function* () {
|
|
89
110
|
var _a;
|
|
@@ -91,8 +112,8 @@ class SolanaUiTransaction {
|
|
|
91
112
|
if (!to) {
|
|
92
113
|
throw new Error('Destination is required');
|
|
93
114
|
}
|
|
94
|
-
if (this.
|
|
95
|
-
return this.
|
|
115
|
+
if (this.multipleTransactions) {
|
|
116
|
+
return this.multipleTransactions;
|
|
96
117
|
}
|
|
97
118
|
const sendTransaction = new Transaction();
|
|
98
119
|
const fromPubkey = new PublicKey(this.from);
|