@pioneer-platform/pioneer-sdk 0.0.82 → 4.14.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.
@@ -0,0 +1,188 @@
1
+ import { caipToNetworkId } from '@pioneer-platform/pioneer-caip';
2
+ import {
3
+ cosmosDelegateTemplate,
4
+ cosmosUndelegateTemplate,
5
+ cosmosRedelegateTemplate,
6
+ cosmosClaimRewardsTemplate,
7
+ cosmosClaimAllRewardsTemplate
8
+ } from './templates/cosmos-staking.js';
9
+
10
+ const TAG = ' | createUnsignedStakingTx | ';
11
+
12
+ export interface StakingTxParams {
13
+ type: 'delegate' | 'undelegate' | 'redelegate' | 'claim_rewards' | 'claim_all_rewards';
14
+ amount?: number;
15
+ validatorAddress?: string;
16
+ validatorSrcAddress?: string; // For redelegate
17
+ validatorDstAddress?: string; // For redelegate
18
+ validatorAddresses?: string[]; // For claim_all_rewards
19
+ memo?: string;
20
+ }
21
+
22
+ export async function createUnsignedStakingTx(
23
+ caip: string,
24
+ params: StakingTxParams,
25
+ pubkeys: any[],
26
+ pioneer: any,
27
+ keepKeySdk: any,
28
+ ): Promise<any> {
29
+ const tag = TAG + ' | createUnsignedStakingTx | ';
30
+
31
+ try {
32
+ if (!pioneer) throw new Error('Failed to init! pioneer');
33
+
34
+ const networkId = caipToNetworkId(caip);
35
+
36
+ // Auto-correct context if wrong network
37
+ if (!keepKeySdk.pubkeyContext?.networks?.includes(networkId)) {
38
+ keepKeySdk.pubkeyContext = pubkeys.find(pk =>
39
+ pk.networks?.includes(networkId)
40
+ );
41
+ }
42
+
43
+ if (!keepKeySdk.pubkeyContext) {
44
+ throw new Error(`No relevant pubkeys found for networkId: ${networkId}`);
45
+ }
46
+
47
+ // Map networkId to chain and get network-specific configs
48
+ let chain: string;
49
+ let chainId: string;
50
+ let denom: string;
51
+ let decimals: number;
52
+ let feeConfig: any;
53
+
54
+ switch (networkId) {
55
+ case 'cosmos:cosmoshub-4':
56
+ chain = 'cosmos';
57
+ chainId = 'cosmoshub-4';
58
+ denom = 'uatom';
59
+ decimals = 6;
60
+ feeConfig = {
61
+ gas: '1500000', // Increased to 1.5M gas to handle all cosmos staking operations
62
+ amount: [{ denom: 'uatom', amount: '37500' }] // Increased proportionally (1,500,000 * 0.025 = 37,500)
63
+ };
64
+ break;
65
+ case 'cosmos:osmosis-1':
66
+ chain = 'osmosis';
67
+ chainId = 'osmosis-1';
68
+ denom = 'uosmo';
69
+ decimals = 6;
70
+ feeConfig = {
71
+ gas: '1000000', // Increased to 1M gas for osmosis staking operations
72
+ amount: [{ denom: 'uosmo', amount: '25000' }] // Increased proportionally
73
+ };
74
+ break;
75
+ default:
76
+ throw new Error(`Unsupported networkId for staking: ${networkId}`);
77
+ }
78
+
79
+ console.log(tag, `Building ${params.type} transaction for ${chain}`);
80
+
81
+ const fromAddress = keepKeySdk.pubkeyContext.address || keepKeySdk.pubkeyContext.pubkey;
82
+
83
+ // Get account info
84
+ const accountInfo = (await pioneer.GetAccountInfo({ network: chain, address: fromAddress }))
85
+ .data;
86
+ console.log(tag, 'accountInfo: ', accountInfo);
87
+
88
+ let account_number: string;
89
+ let sequence: string;
90
+
91
+ if (networkId === 'cosmos:cosmoshub-4' || networkId === 'cosmos:osmosis-1') {
92
+ account_number = accountInfo.account.account_number || '0';
93
+ sequence = accountInfo.account.sequence || '0';
94
+ } else {
95
+ throw new Error(`Unsupported account info format for: ${networkId}`);
96
+ }
97
+
98
+ // Convert amount to smallest unit if provided
99
+ let amountInSmallestUnit: string = '0';
100
+ if (params.amount) {
101
+ amountInSmallestUnit = Math.floor(params.amount * Math.pow(10, decimals)).toString();
102
+ }
103
+
104
+ const commonParams = {
105
+ account_number,
106
+ chain_id: chainId,
107
+ fee: feeConfig,
108
+ from_address: fromAddress,
109
+ memo: params.memo || '',
110
+ sequence,
111
+ };
112
+
113
+ // Build transaction based on type
114
+ switch (params.type) {
115
+ case 'delegate':
116
+ if (!params.validatorAddress) {
117
+ throw new Error('validatorAddress is required for delegate transaction');
118
+ }
119
+ if (!params.amount) {
120
+ throw new Error('amount is required for delegate transaction');
121
+ }
122
+
123
+ return cosmosDelegateTemplate({
124
+ ...commonParams,
125
+ validator_address: params.validatorAddress,
126
+ amount: amountInSmallestUnit,
127
+ denom,
128
+ });
129
+
130
+ case 'undelegate':
131
+ if (!params.validatorAddress) {
132
+ throw new Error('validatorAddress is required for undelegate transaction');
133
+ }
134
+ if (!params.amount) {
135
+ throw new Error('amount is required for undelegate transaction');
136
+ }
137
+
138
+ return cosmosUndelegateTemplate({
139
+ ...commonParams,
140
+ validator_address: params.validatorAddress,
141
+ amount: amountInSmallestUnit,
142
+ denom,
143
+ });
144
+
145
+ case 'redelegate':
146
+ if (!params.validatorSrcAddress || !params.validatorDstAddress) {
147
+ throw new Error('validatorSrcAddress and validatorDstAddress are required for redelegate transaction');
148
+ }
149
+ if (!params.amount) {
150
+ throw new Error('amount is required for redelegate transaction');
151
+ }
152
+
153
+ return cosmosRedelegateTemplate({
154
+ ...commonParams,
155
+ validator_src_address: params.validatorSrcAddress,
156
+ validator_dst_address: params.validatorDstAddress,
157
+ amount: amountInSmallestUnit,
158
+ denom,
159
+ });
160
+
161
+ case 'claim_rewards':
162
+ if (!params.validatorAddress) {
163
+ throw new Error('validatorAddress is required for claim_rewards transaction');
164
+ }
165
+
166
+ return cosmosClaimRewardsTemplate({
167
+ ...commonParams,
168
+ validator_address: params.validatorAddress,
169
+ });
170
+
171
+ case 'claim_all_rewards':
172
+ if (!params.validatorAddresses || params.validatorAddresses.length === 0) {
173
+ throw new Error('validatorAddresses is required for claim_all_rewards transaction');
174
+ }
175
+
176
+ return cosmosClaimAllRewardsTemplate({
177
+ ...commonParams,
178
+ validator_addresses: params.validatorAddresses,
179
+ });
180
+
181
+ default:
182
+ throw new Error(`Unsupported staking transaction type: ${params.type}`);
183
+ }
184
+ } catch (error) {
185
+ console.error(tag, 'Error:', error);
186
+ throw error;
187
+ }
188
+ }
@@ -0,0 +1,249 @@
1
+ import { caipToNetworkId } from '@pioneer-platform/pioneer-caip';
2
+
3
+ import { cosmosTransferTemplate } from './templates/cosmos';
4
+ import { mayachainDepositTemplate, mayachainTransferTemplate } from './templates/mayachain';
5
+ import { osmosisTransferTemplate } from './templates/osmosis';
6
+ import { thorchainDepositTemplate, thorchainTransferTemplate } from './templates/thorchain';
7
+
8
+ const TAG = ' | createUnsignedTendermintTx | ';
9
+
10
+ export async function createUnsignedTendermintTx(
11
+ caip: string,
12
+ type: string,
13
+ amount: number,
14
+ memo: string,
15
+ pubkeys: any[],
16
+ pioneer: any,
17
+ keepKeySdk: any,
18
+ isMax: boolean,
19
+ to?: string,
20
+ ): Promise<any> {
21
+ const tag = TAG + ' | createUnsignedTendermintTx | ';
22
+
23
+ try {
24
+ if (!pioneer) throw new Error('Failed to init! pioneer');
25
+
26
+ const networkId = caipToNetworkId(caip);
27
+
28
+ // Auto-correct context if wrong network
29
+ if (!keepKeySdk.pubkeyContext?.networks?.includes(networkId)) {
30
+ keepKeySdk.pubkeyContext = pubkeys.find(pk =>
31
+ pk.networks?.includes(networkId)
32
+ );
33
+ }
34
+
35
+ if (!keepKeySdk.pubkeyContext) {
36
+ throw new Error(`No relevant pubkeys found for networkId: ${networkId}`);
37
+ }
38
+
39
+ // Map networkId to a human-readable chain
40
+ let chain: string;
41
+ switch (networkId) {
42
+ case 'cosmos:thorchain-mainnet-v1':
43
+ chain = 'thorchain';
44
+ break;
45
+ case 'cosmos:mayachain-mainnet-v1':
46
+ chain = 'mayachain';
47
+ break;
48
+ case 'cosmos:cosmoshub-4':
49
+ chain = 'cosmos';
50
+ break;
51
+ case 'cosmos:osmosis-1':
52
+ chain = 'osmosis';
53
+ break;
54
+ default:
55
+ throw new Error(`Unhandled networkId: ${networkId}`);
56
+ }
57
+
58
+ //console.log(tag, `Resolved chain: ${chain} for networkId: ${networkId}`);
59
+
60
+ const fromAddress = keepKeySdk.pubkeyContext.address || keepKeySdk.pubkeyContext.pubkey;
61
+ let asset = caip.split(':')[1]; // Assuming format is "network:asset"
62
+ const accountInfo = (await pioneer.GetAccountInfo({ network: chain, address: fromAddress }))
63
+ .data;
64
+ //console.log('accountInfo: ', accountInfo);
65
+ let balanceInfo = await pioneer.GetPubkeyBalance({ asset: chain, pubkey: fromAddress });
66
+ //console.log(tag, `balanceInfo: `, balanceInfo);
67
+
68
+ let account_number, sequence;
69
+ if (networkId === 'cosmos:cosmoshub-4' || networkId === 'cosmos:osmosis-1') {
70
+ account_number = accountInfo.account.account_number || '0';
71
+ sequence = accountInfo.account.sequence || '0';
72
+ } else if (
73
+ networkId === 'cosmos:thorchain-mainnet-v1' ||
74
+ networkId === 'cosmos:mayachain-mainnet-v1'
75
+ ) {
76
+ account_number = accountInfo.result.value.account_number || '0';
77
+ sequence = accountInfo.result.value.sequence || '0';
78
+ }
79
+
80
+ const fees = {
81
+ 'cosmos:thorchain-mainnet-v1': 0.02,
82
+ 'cosmos:mayachain-mainnet-v1': 0.2,
83
+ 'cosmos:cosmoshub-4': 0.005,
84
+ 'cosmos:osmosis-1': 0.035,
85
+ };
86
+
87
+ switch (networkId) {
88
+ case 'cosmos:thorchain-mainnet-v1': {
89
+ if (isMax) {
90
+ //console.log('isMax detected! Adjusting amount for fees...');
91
+ const fee = 2000000; // Convert fee to smallest unit
92
+ amount = Math.floor(Math.max(0, balanceInfo.data * 1e8 - fee)); // Adjust amount for fees if isMax
93
+ } else {
94
+ amount = Math.floor(amount * 1e8); // Convert amount to smallest unit
95
+ }
96
+ asset = 'rune';
97
+ //console.log(tag, `amount: ${amount}, isMax: ${isMax}, fee: ${fees[networkId]}`);
98
+ return to
99
+ ? thorchainTransferTemplate({
100
+ account_number,
101
+ chain_id: 'thorchain-1',
102
+ fee: {
103
+ gas: '500000000',
104
+ amount: [
105
+ {
106
+ amount: '0',
107
+ denom: 'rune',
108
+ },
109
+ ],
110
+ },
111
+ from_address: fromAddress,
112
+ to_address: to,
113
+ asset,
114
+ amount: amount.toString(),
115
+ memo,
116
+ sequence,
117
+ })
118
+ : thorchainDepositTemplate({
119
+ account_number,
120
+ chain_id: 'thorchain-1',
121
+ fee: {
122
+ gas: '500000000',
123
+ amount: [
124
+ {
125
+ amount: '0',
126
+ denom: 'rune',
127
+ },
128
+ ],
129
+ },
130
+ from_address: fromAddress,
131
+ asset,
132
+ amount: amount.toString(),
133
+ memo,
134
+ sequence,
135
+ });
136
+ }
137
+
138
+ case 'cosmos:mayachain-mainnet-v1': {
139
+ // Determine the correct asset based on CAIP
140
+ let mayaAsset: string;
141
+ if (caip.includes('/denom:maya')) {
142
+ mayaAsset = 'MAYA.MAYA'; // MAYA token
143
+ } else if (caip.includes('/slip44:931')) {
144
+ mayaAsset = 'MAYA.CACAO'; // CACAO (native)
145
+ } else {
146
+ throw new Error(`Unsupported Maya chain CAIP: ${caip}`);
147
+ }
148
+
149
+ if (isMax) {
150
+ const fee = Math.floor(fees[networkId] * 1e10); // Convert fee to smallest unit and floor to int
151
+ amount = Math.max(0, Math.floor(balanceInfo.data * 1e10) - fee); // Floor to ensure no decimals
152
+ } else {
153
+ amount = Math.max(Math.floor(amount * 1e10), 0); // Floor the multiplication result
154
+ }
155
+
156
+ //console.log(tag, `amount: ${amount}, isMax: ${isMax}, fee: ${fees[networkId]}, asset: ${mayaAsset}`);
157
+ return to
158
+ ? mayachainTransferTemplate({
159
+ account_number,
160
+ chain_id: 'mayachain-mainnet-v1',
161
+ fee: {
162
+ gas: '500000000',
163
+ amount: [
164
+ {
165
+ amount: '0',
166
+ denom: 'cacao',
167
+ },
168
+ ],
169
+ },
170
+ from_address: fromAddress,
171
+ to_address: to,
172
+ asset: mayaAsset,
173
+ amount: amount.toString(),
174
+ memo,
175
+ sequence,
176
+ })
177
+ : mayachainDepositTemplate({
178
+ account_number,
179
+ chain_id: 'mayachain-mainnet-v1',
180
+ fee: {
181
+ gas: '500000000',
182
+ amount: [
183
+ {
184
+ amount: '0',
185
+ denom: 'cacao',
186
+ },
187
+ ],
188
+ },
189
+ from_address: fromAddress,
190
+ asset: mayaAsset,
191
+ amount: amount.toString(),
192
+ memo,
193
+ sequence,
194
+ });
195
+ }
196
+
197
+ case 'cosmos:cosmoshub-4': {
198
+ if (isMax) {
199
+ const fee = fees[networkId] * 1e6; // Convert fee to smallest unit
200
+ amount = Math.max(0, amount * 1e6 - fee); // Adjust amount for fees if isMax
201
+ } else {
202
+ amount = amount * 1e4; // Convert amount to smallest unit
203
+ }
204
+ return cosmosTransferTemplate({
205
+ account_number,
206
+ chain_id: 'cosmoshub-4',
207
+ fee: { gas: '1000000', amount: [] }, // Increased from 200k to 1M gas
208
+ from_address: fromAddress,
209
+ to_address: to,
210
+ asset: 'uatom',
211
+ amount: amount.toString(),
212
+ memo,
213
+ sequence,
214
+ });
215
+ }
216
+
217
+ case 'cosmos:osmosis-1': {
218
+ if (isMax) {
219
+ const fee = fees[networkId] * 1e6; // Convert fee to smallest unit
220
+ amount = Math.max(0, amount * 1e6 - fee); // Adjust amount for fees if isMax
221
+ } else {
222
+ amount = amount * 1e4; // Convert amount to smallest unit
223
+ }
224
+ const DEFAULT_OSMO_FEE_MAINNET = {
225
+ amount: [{ denom: 'uosmo', amount: '10000' }], // Increased fee amount
226
+ gas: '1000000', // Increased from 500k to 1M gas
227
+ };
228
+ return osmosisTransferTemplate({
229
+ account_number,
230
+ chain_id: 'osmosis-1',
231
+ fee: DEFAULT_OSMO_FEE_MAINNET,
232
+ from_address: fromAddress,
233
+ to_address: to,
234
+ asset: 'uosmo',
235
+ amount: amount.toString(),
236
+ memo,
237
+ sequence,
238
+ });
239
+ }
240
+
241
+ default: {
242
+ throw new Error(`Unsupported networkId: ${networkId}`);
243
+ }
244
+ }
245
+ } catch (error) {
246
+ console.error(tag, 'Error:', error);
247
+ throw error;
248
+ }
249
+ }