jay-network 0.1.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/LICENSE +21 -0
- package/README.md +138 -0
- package/dist/index.cjs +426 -0
- package/dist/index.d.cts +216 -0
- package/dist/index.d.ts +216 -0
- package/dist/index.js +371 -0
- package/package.json +58 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Winnode
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
# jay-network
|
|
2
|
+
|
|
3
|
+
JavaScript / TypeScript SDK for **[The Jay Network](https://thejaynetwork.com)** — a Cosmos SDK Layer‑1 with CosmWasm and IBC. Built on [CosmJS](https://github.com/cosmos/cosmjs).
|
|
4
|
+
|
|
5
|
+
- **`JayClient`** — read-only queries (balances, validators, governance, IBC, supply)
|
|
6
|
+
- **`JaySigningClient`** — transactions (send, stake, redelegate, claim, vote, IBC)
|
|
7
|
+
- Chain constants + address helpers
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install jay-network
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Network
|
|
14
|
+
|
|
15
|
+
| Parameter | Value |
|
|
16
|
+
|-----------|-------|
|
|
17
|
+
| Chain ID | `thejaynetwork` |
|
|
18
|
+
| Token | `JAY` (`ujay`, 6 decimals) |
|
|
19
|
+
| Address prefix | `yjay` |
|
|
20
|
+
| RPC | `https://pixture.thejaynetwork.com/rpc` |
|
|
21
|
+
| REST | `https://pixture.thejaynetwork.com/rest` |
|
|
22
|
+
|
|
23
|
+
## Querying (no wallet)
|
|
24
|
+
|
|
25
|
+
```ts
|
|
26
|
+
import { JayClient } from 'jay-network'
|
|
27
|
+
|
|
28
|
+
const jay = new JayClient()
|
|
29
|
+
|
|
30
|
+
const { height } = await jay.getLatestBlock()
|
|
31
|
+
const balance = await jay.getJayBalance('yjay1...')
|
|
32
|
+
const validators = await jay.getValidators()
|
|
33
|
+
const proposals = await jay.getProposals()
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Use custom endpoints:
|
|
37
|
+
|
|
38
|
+
```ts
|
|
39
|
+
const jay = new JayClient({
|
|
40
|
+
rpc: 'https://my-node:26657',
|
|
41
|
+
rest: 'https://my-node:1317',
|
|
42
|
+
})
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Transactions (with a wallet)
|
|
46
|
+
|
|
47
|
+
`JaySigningClient` works with any CosmJS `OfflineSigner` — Keplr, JAY Wallet, or a mnemonic.
|
|
48
|
+
|
|
49
|
+
### Keplr / JAY Wallet (browser)
|
|
50
|
+
|
|
51
|
+
```ts
|
|
52
|
+
import { JaySigningClient, JAY_CHAIN_INFO, JAY_CHAIN_ID } from 'jay-network'
|
|
53
|
+
|
|
54
|
+
await window.keplr.experimentalSuggestChain(JAY_CHAIN_INFO)
|
|
55
|
+
await window.keplr.enable(JAY_CHAIN_ID)
|
|
56
|
+
|
|
57
|
+
const signer = await window.keplr.getOfflineSignerAuto(JAY_CHAIN_ID)
|
|
58
|
+
const [account] = await signer.getAccounts()
|
|
59
|
+
|
|
60
|
+
const jay = await JaySigningClient.connect(signer, account.address)
|
|
61
|
+
|
|
62
|
+
await jay.send('yjay1recipient...', '5') // send 5 JAY
|
|
63
|
+
await jay.delegate('yjayvaloper1...', '100') // stake 100 JAY
|
|
64
|
+
await jay.claimRewards('yjayvaloper1...') // claim rewards
|
|
65
|
+
await jay.vote(12, 'VOTE_OPTION_YES') // vote on proposal #12
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Node.js (mnemonic)
|
|
69
|
+
|
|
70
|
+
```ts
|
|
71
|
+
import { DirectSecp256k1HdWallet } from '@cosmjs/proto-signing'
|
|
72
|
+
import { JaySigningClient, JAY_PREFIX } from 'jay-network'
|
|
73
|
+
|
|
74
|
+
const signer = await DirectSecp256k1HdWallet.fromMnemonic(process.env.MNEMONIC!, {
|
|
75
|
+
prefix: JAY_PREFIX,
|
|
76
|
+
})
|
|
77
|
+
const [account] = await signer.getAccounts()
|
|
78
|
+
|
|
79
|
+
const jay = await JaySigningClient.connect(signer, account.address)
|
|
80
|
+
await jay.send('yjay1...', '1')
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## IBC transfer
|
|
84
|
+
|
|
85
|
+
```ts
|
|
86
|
+
await jay.ibcTransfer({
|
|
87
|
+
sourceChannel: 'channel-0',
|
|
88
|
+
receiver: 'cosmos1...',
|
|
89
|
+
amount: '2.5',
|
|
90
|
+
})
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## Helpers
|
|
94
|
+
|
|
95
|
+
```ts
|
|
96
|
+
import {
|
|
97
|
+
toMicro, fromMicro, reEncodeAddress, toValoper,
|
|
98
|
+
isValidatorOperator, isValidJayAddress, shortenAddress,
|
|
99
|
+
} from 'jay-network'
|
|
100
|
+
|
|
101
|
+
toMicro('1.5') // "1500000"
|
|
102
|
+
fromMicro('1500000') // "1.500000"
|
|
103
|
+
reEncodeAddress('yjay1...', 'cosmos')// "cosmos1..."
|
|
104
|
+
toValoper('yjay1...') // "yjayvaloper1..."
|
|
105
|
+
isValidJayAddress('yjay1...') // true
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## API
|
|
109
|
+
|
|
110
|
+
### `JayClient(options?)`
|
|
111
|
+
`getLatestBlock` · `getNodeInfo` · `getBalances` · `getJayBalance` · `getValidators` · `getValidator` · `getDelegations` · `getRewards` · `getValidatorCommission` · `getProposals` · `getProposal` · `getSupply` · `getIbcChannels` · `resolveIbcDenom`
|
|
112
|
+
|
|
113
|
+
### `JaySigningClient.connect(signer, address, options?)`
|
|
114
|
+
`send` · `delegate` · `undelegate` · `redelegate` · `claimRewards` · `claimAllRewards` · `withdrawCommission` · `vote` · `ibcTransfer` · `disconnect`
|
|
115
|
+
|
|
116
|
+
Every tx method accepts an optional `memo` and an optional explicit `StdFee` (pass a plain fee object, not a `GasPrice` instance).
|
|
117
|
+
|
|
118
|
+
## Publishing (maintainers)
|
|
119
|
+
|
|
120
|
+
This package lives in the [hub-jay](https://github.com/Winnode/hub-jay) repo (under `jaynetwork-sdk/`) and auto-publishes to npm via GitHub Actions.
|
|
121
|
+
|
|
122
|
+
**One-time setup**
|
|
123
|
+
1. Create an npm **Automation** access token at npmjs.com → Access Tokens.
|
|
124
|
+
2. In the hub-jay repo: Settings → Secrets and variables → Actions → New repository secret.
|
|
125
|
+
- Name: `NPM_TOKEN`
|
|
126
|
+
- Value: the npm token
|
|
127
|
+
- Never commit the token to the repo.
|
|
128
|
+
|
|
129
|
+
**Release flow**
|
|
130
|
+
1. Bump the version in `jaynetwork-sdk/package.json`.
|
|
131
|
+
2. Create a GitHub Release in the hub-jay repo.
|
|
132
|
+
3. The `Publish SDK to npm` workflow builds `jaynetwork-sdk/` and runs `npm publish --access public`.
|
|
133
|
+
|
|
134
|
+
You can also trigger it manually from the Actions tab (workflow_dispatch).
|
|
135
|
+
|
|
136
|
+
## License
|
|
137
|
+
|
|
138
|
+
MIT © [Winnode](https://github.com/Winnode)
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,426 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/index.ts
|
|
31
|
+
var index_exports = {};
|
|
32
|
+
__export(index_exports, {
|
|
33
|
+
DEFAULT_REST: () => DEFAULT_REST,
|
|
34
|
+
DEFAULT_RPC: () => DEFAULT_RPC,
|
|
35
|
+
JAY_CHAIN_ID: () => JAY_CHAIN_ID,
|
|
36
|
+
JAY_CHAIN_INFO: () => JAY_CHAIN_INFO,
|
|
37
|
+
JAY_CHAIN_NAME: () => JAY_CHAIN_NAME,
|
|
38
|
+
JAY_DECIMALS: () => JAY_DECIMALS,
|
|
39
|
+
JAY_DENOM: () => JAY_DENOM,
|
|
40
|
+
JAY_PREFIX: () => JAY_PREFIX,
|
|
41
|
+
JAY_SYMBOL: () => JAY_SYMBOL,
|
|
42
|
+
JayClient: () => JayClient,
|
|
43
|
+
JaySigningClient: () => JaySigningClient,
|
|
44
|
+
fromMicro: () => fromMicro,
|
|
45
|
+
isValidJayAddress: () => isValidJayAddress,
|
|
46
|
+
isValidatorOperator: () => isValidatorOperator,
|
|
47
|
+
jayCoin: () => jayCoin,
|
|
48
|
+
reEncodeAddress: () => reEncodeAddress,
|
|
49
|
+
shortenAddress: () => shortenAddress,
|
|
50
|
+
toMicro: () => toMicro,
|
|
51
|
+
toValoper: () => toValoper
|
|
52
|
+
});
|
|
53
|
+
module.exports = __toCommonJS(index_exports);
|
|
54
|
+
|
|
55
|
+
// src/chain.ts
|
|
56
|
+
var JAY_CHAIN_ID = "thejaynetwork";
|
|
57
|
+
var JAY_CHAIN_NAME = "Jay Network";
|
|
58
|
+
var JAY_DENOM = "ujay";
|
|
59
|
+
var JAY_SYMBOL = "JAY";
|
|
60
|
+
var JAY_DECIMALS = 6;
|
|
61
|
+
var JAY_PREFIX = "yjay";
|
|
62
|
+
var DEFAULT_RPC = "https://pixture.thejaynetwork.com/rpc";
|
|
63
|
+
var DEFAULT_REST = "https://pixture.thejaynetwork.com/rest";
|
|
64
|
+
var JAY_CHAIN_INFO = {
|
|
65
|
+
chainId: JAY_CHAIN_ID,
|
|
66
|
+
chainName: JAY_CHAIN_NAME,
|
|
67
|
+
rpc: DEFAULT_RPC,
|
|
68
|
+
rest: DEFAULT_REST,
|
|
69
|
+
bip44: { coinType: 118 },
|
|
70
|
+
bech32Config: {
|
|
71
|
+
bech32PrefixAccAddr: JAY_PREFIX,
|
|
72
|
+
bech32PrefixAccPub: `${JAY_PREFIX}pub`,
|
|
73
|
+
bech32PrefixValAddr: `${JAY_PREFIX}valoper`,
|
|
74
|
+
bech32PrefixValPub: `${JAY_PREFIX}valoperpub`,
|
|
75
|
+
bech32PrefixConsAddr: `${JAY_PREFIX}valcons`,
|
|
76
|
+
bech32PrefixConsPub: `${JAY_PREFIX}valconspub`
|
|
77
|
+
},
|
|
78
|
+
currencies: [
|
|
79
|
+
{ coinDenom: JAY_SYMBOL, coinMinimalDenom: JAY_DENOM, coinDecimals: JAY_DECIMALS }
|
|
80
|
+
],
|
|
81
|
+
feeCurrencies: [
|
|
82
|
+
{
|
|
83
|
+
coinDenom: JAY_SYMBOL,
|
|
84
|
+
coinMinimalDenom: JAY_DENOM,
|
|
85
|
+
coinDecimals: JAY_DECIMALS,
|
|
86
|
+
gasPriceStep: { low: 0.01, average: 0.025, high: 0.04 }
|
|
87
|
+
}
|
|
88
|
+
],
|
|
89
|
+
stakeCurrency: {
|
|
90
|
+
coinDenom: JAY_SYMBOL,
|
|
91
|
+
coinMinimalDenom: JAY_DENOM,
|
|
92
|
+
coinDecimals: JAY_DECIMALS
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
// src/utils.ts
|
|
97
|
+
var import_encoding = require("@cosmjs/encoding");
|
|
98
|
+
function toMicro(amount, decimals = JAY_DECIMALS) {
|
|
99
|
+
const n = typeof amount === "string" ? parseFloat(amount) : amount;
|
|
100
|
+
if (!isFinite(n)) throw new Error(`Invalid amount: ${amount}`);
|
|
101
|
+
return Math.floor(n * Math.pow(10, decimals)).toString();
|
|
102
|
+
}
|
|
103
|
+
function fromMicro(amount, decimals = JAY_DECIMALS) {
|
|
104
|
+
const n = typeof amount === "string" ? parseInt(amount, 10) : amount;
|
|
105
|
+
return (n / Math.pow(10, decimals)).toFixed(decimals);
|
|
106
|
+
}
|
|
107
|
+
function jayCoin(amount, denom = JAY_DENOM) {
|
|
108
|
+
return { denom, amount: toMicro(amount) };
|
|
109
|
+
}
|
|
110
|
+
function reEncodeAddress(address, prefix) {
|
|
111
|
+
const { data } = (0, import_encoding.fromBech32)(address);
|
|
112
|
+
return (0, import_encoding.toBech32)(prefix, data);
|
|
113
|
+
}
|
|
114
|
+
function toValoper(accountAddress) {
|
|
115
|
+
const { prefix, data } = (0, import_encoding.fromBech32)(accountAddress);
|
|
116
|
+
return (0, import_encoding.toBech32)(`${prefix}valoper`, data);
|
|
117
|
+
}
|
|
118
|
+
function isValidatorOperator(accountAddress, valoperAddress) {
|
|
119
|
+
try {
|
|
120
|
+
return toValoper(accountAddress) === valoperAddress;
|
|
121
|
+
} catch {
|
|
122
|
+
return false;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
function isValidJayAddress(address) {
|
|
126
|
+
try {
|
|
127
|
+
return (0, import_encoding.fromBech32)(address).prefix === JAY_PREFIX;
|
|
128
|
+
} catch {
|
|
129
|
+
return false;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
function shortenAddress(address, head = 10, tail = 6) {
|
|
133
|
+
if (!address || address.length <= head + tail) return address;
|
|
134
|
+
return `${address.slice(0, head)}\u2026${address.slice(-tail)}`;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// src/client.ts
|
|
138
|
+
var JayClient = class {
|
|
139
|
+
constructor(options = {}) {
|
|
140
|
+
this.rpc = options.rpc ?? DEFAULT_RPC;
|
|
141
|
+
this.rest = options.rest ?? DEFAULT_REST;
|
|
142
|
+
}
|
|
143
|
+
async getJson(base, path) {
|
|
144
|
+
const res = await fetch(`${base}${path}`);
|
|
145
|
+
if (!res.ok) throw new Error(`Request failed (${res.status}): ${path}`);
|
|
146
|
+
return res.json();
|
|
147
|
+
}
|
|
148
|
+
/** Latest block height and time from the RPC status endpoint. */
|
|
149
|
+
async getLatestBlock() {
|
|
150
|
+
const data = await this.getJson(this.rpc, "/status");
|
|
151
|
+
const info = data.result.sync_info;
|
|
152
|
+
return { height: info.latest_block_height, time: info.latest_block_time };
|
|
153
|
+
}
|
|
154
|
+
/** Node sync / network identity info. */
|
|
155
|
+
async getNodeInfo() {
|
|
156
|
+
return this.getJson(this.rest, "/cosmos/base/tendermint/v1beta1/node_info");
|
|
157
|
+
}
|
|
158
|
+
/** All balances for an address. Amounts are in base units (ujay). */
|
|
159
|
+
async getBalances(address) {
|
|
160
|
+
const data = await this.getJson(
|
|
161
|
+
this.rest,
|
|
162
|
+
`/cosmos/bank/v1beta1/balances/${address}?pagination.limit=200`
|
|
163
|
+
);
|
|
164
|
+
return data.balances ?? [];
|
|
165
|
+
}
|
|
166
|
+
/** Native JAY balance as a human-readable string. */
|
|
167
|
+
async getJayBalance(address) {
|
|
168
|
+
const balances = await this.getBalances(address);
|
|
169
|
+
const jay = balances.find((c) => c.denom === JAY_DENOM);
|
|
170
|
+
return fromMicro(jay?.amount ?? "0");
|
|
171
|
+
}
|
|
172
|
+
/** Bonded validators (optionally filter by status). */
|
|
173
|
+
async getValidators(status = "BOND_STATUS_BONDED") {
|
|
174
|
+
const data = await this.getJson(
|
|
175
|
+
this.rest,
|
|
176
|
+
`/cosmos/staking/v1beta1/validators?status=${status}&pagination.limit=500`
|
|
177
|
+
);
|
|
178
|
+
return data.validators ?? [];
|
|
179
|
+
}
|
|
180
|
+
/** A single validator by operator (valoper) address. */
|
|
181
|
+
async getValidator(valoperAddress) {
|
|
182
|
+
const data = await this.getJson(
|
|
183
|
+
this.rest,
|
|
184
|
+
`/cosmos/staking/v1beta1/validators/${valoperAddress}`
|
|
185
|
+
);
|
|
186
|
+
return data.validator;
|
|
187
|
+
}
|
|
188
|
+
/** All delegations for a delegator. */
|
|
189
|
+
async getDelegations(delegatorAddress) {
|
|
190
|
+
const data = await this.getJson(
|
|
191
|
+
this.rest,
|
|
192
|
+
`/cosmos/staking/v1beta1/delegations/${delegatorAddress}`
|
|
193
|
+
);
|
|
194
|
+
return data.delegation_responses ?? [];
|
|
195
|
+
}
|
|
196
|
+
/** Pending staking rewards for a delegator across all validators. */
|
|
197
|
+
async getRewards(delegatorAddress) {
|
|
198
|
+
const data = await this.getJson(
|
|
199
|
+
this.rest,
|
|
200
|
+
`/cosmos/distribution/v1beta1/delegators/${delegatorAddress}/rewards`
|
|
201
|
+
);
|
|
202
|
+
return data;
|
|
203
|
+
}
|
|
204
|
+
/** Validator commission accrued by an operator. */
|
|
205
|
+
async getValidatorCommission(valoperAddress) {
|
|
206
|
+
const data = await this.getJson(
|
|
207
|
+
this.rest,
|
|
208
|
+
`/cosmos/distribution/v1beta1/validators/${valoperAddress}/commission`
|
|
209
|
+
);
|
|
210
|
+
const jay = data.commission?.commission?.find(
|
|
211
|
+
(c) => c.denom === JAY_DENOM
|
|
212
|
+
);
|
|
213
|
+
return fromMicro(jay?.amount ?? "0");
|
|
214
|
+
}
|
|
215
|
+
/** Governance proposals (optionally filter by status). */
|
|
216
|
+
async getProposals(status) {
|
|
217
|
+
const q = status ? `?proposal_status=${status}` : "";
|
|
218
|
+
const data = await this.getJson(this.rest, `/cosmos/gov/v1/proposals${q}`);
|
|
219
|
+
return data.proposals ?? [];
|
|
220
|
+
}
|
|
221
|
+
/** A single governance proposal by id. */
|
|
222
|
+
async getProposal(proposalId) {
|
|
223
|
+
const data = await this.getJson(this.rest, `/cosmos/gov/v1/proposals/${proposalId}`);
|
|
224
|
+
return data.proposal;
|
|
225
|
+
}
|
|
226
|
+
/** Total token supply. */
|
|
227
|
+
async getSupply() {
|
|
228
|
+
const data = await this.getJson(this.rest, "/cosmos/bank/v1beta1/supply?pagination.limit=50");
|
|
229
|
+
return data.supply ?? [];
|
|
230
|
+
}
|
|
231
|
+
/** Open IBC transfer channels. */
|
|
232
|
+
async getIbcChannels() {
|
|
233
|
+
const data = await this.getJson(
|
|
234
|
+
this.rest,
|
|
235
|
+
"/ibc/core/channel/v1/channels?pagination.limit=300"
|
|
236
|
+
);
|
|
237
|
+
return (data.channels ?? []).filter(
|
|
238
|
+
(c) => c.state === "STATE_OPEN" && c.port_id === "transfer"
|
|
239
|
+
);
|
|
240
|
+
}
|
|
241
|
+
/** Resolve an `ibc/<hash>` denom to its base denom + path. */
|
|
242
|
+
async resolveIbcDenom(denom) {
|
|
243
|
+
if (!denom.startsWith("ibc/")) return { baseDenom: denom, path: "" };
|
|
244
|
+
const hash = denom.slice(4);
|
|
245
|
+
const data = await this.getJson(
|
|
246
|
+
this.rest,
|
|
247
|
+
`/ibc/apps/transfer/v1/denom_traces/${hash}`
|
|
248
|
+
);
|
|
249
|
+
const trace = data.denom_trace;
|
|
250
|
+
return { baseDenom: trace?.base_denom ?? denom, path: trace?.path ?? "" };
|
|
251
|
+
}
|
|
252
|
+
};
|
|
253
|
+
|
|
254
|
+
// src/signer.ts
|
|
255
|
+
var import_stargate = require("@cosmjs/stargate");
|
|
256
|
+
var import_long = __toESM(require("long"), 1);
|
|
257
|
+
var VOTE_ENUM = {
|
|
258
|
+
VOTE_OPTION_YES: 1,
|
|
259
|
+
VOTE_OPTION_ABSTAIN: 2,
|
|
260
|
+
VOTE_OPTION_NO: 3,
|
|
261
|
+
VOTE_OPTION_NO_WITH_VETO: 4
|
|
262
|
+
};
|
|
263
|
+
function defaultFee(gas = "250000", amount = "7500") {
|
|
264
|
+
return { amount: [{ denom: JAY_DENOM, amount }], gas };
|
|
265
|
+
}
|
|
266
|
+
var JaySigningClient = class _JaySigningClient {
|
|
267
|
+
constructor(client, address) {
|
|
268
|
+
this.client = client;
|
|
269
|
+
this.address = address;
|
|
270
|
+
}
|
|
271
|
+
/** Connect using an offline signer and the sender address. */
|
|
272
|
+
static async connect(signer, address, options = {}) {
|
|
273
|
+
const rpc = options.rpc ?? DEFAULT_RPC;
|
|
274
|
+
const client = await import_stargate.SigningStargateClient.connectWithSigner(rpc, signer);
|
|
275
|
+
return new _JaySigningClient(client, address);
|
|
276
|
+
}
|
|
277
|
+
/** Underlying CosmJS client for advanced use. */
|
|
278
|
+
get raw() {
|
|
279
|
+
return this.client;
|
|
280
|
+
}
|
|
281
|
+
async broadcast(messages, memo = "", fee) {
|
|
282
|
+
const result = await this.client.signAndBroadcast(
|
|
283
|
+
this.address,
|
|
284
|
+
messages,
|
|
285
|
+
fee ?? defaultFee(),
|
|
286
|
+
memo
|
|
287
|
+
);
|
|
288
|
+
if (result.code !== void 0 && result.code !== 0) {
|
|
289
|
+
throw new Error(`Transaction failed: ${result.rawLog}`);
|
|
290
|
+
}
|
|
291
|
+
return { txHash: result.transactionHash, height: result.height, raw: result };
|
|
292
|
+
}
|
|
293
|
+
/** Send JAY to another address. */
|
|
294
|
+
async send(to, amount, memo = "", fee) {
|
|
295
|
+
const msg = {
|
|
296
|
+
typeUrl: "/cosmos.bank.v1beta1.MsgSend",
|
|
297
|
+
value: {
|
|
298
|
+
fromAddress: this.address,
|
|
299
|
+
toAddress: to,
|
|
300
|
+
amount: [{ denom: JAY_DENOM, amount: toMicro(amount) }]
|
|
301
|
+
}
|
|
302
|
+
};
|
|
303
|
+
return this.broadcast([msg], memo, fee);
|
|
304
|
+
}
|
|
305
|
+
/** Delegate (stake) JAY to a validator. */
|
|
306
|
+
async delegate(valoperAddress, amount, memo = "", fee) {
|
|
307
|
+
const msg = {
|
|
308
|
+
typeUrl: "/cosmos.staking.v1beta1.MsgDelegate",
|
|
309
|
+
value: {
|
|
310
|
+
delegatorAddress: this.address,
|
|
311
|
+
validatorAddress: valoperAddress,
|
|
312
|
+
amount: { denom: JAY_DENOM, amount: toMicro(amount) }
|
|
313
|
+
}
|
|
314
|
+
};
|
|
315
|
+
return this.broadcast([msg], memo, fee);
|
|
316
|
+
}
|
|
317
|
+
/** Undelegate (unstake) JAY from a validator. */
|
|
318
|
+
async undelegate(valoperAddress, amount, memo = "", fee) {
|
|
319
|
+
const msg = {
|
|
320
|
+
typeUrl: "/cosmos.staking.v1beta1.MsgUndelegate",
|
|
321
|
+
value: {
|
|
322
|
+
delegatorAddress: this.address,
|
|
323
|
+
validatorAddress: valoperAddress,
|
|
324
|
+
amount: { denom: JAY_DENOM, amount: toMicro(amount) }
|
|
325
|
+
}
|
|
326
|
+
};
|
|
327
|
+
return this.broadcast([msg], memo, fee);
|
|
328
|
+
}
|
|
329
|
+
/** Move stake from one validator to another. */
|
|
330
|
+
async redelegate(srcValoper, dstValoper, amount, memo = "", fee) {
|
|
331
|
+
const msg = {
|
|
332
|
+
typeUrl: "/cosmos.staking.v1beta1.MsgBeginRedelegate",
|
|
333
|
+
value: {
|
|
334
|
+
delegatorAddress: this.address,
|
|
335
|
+
validatorSrcAddress: srcValoper,
|
|
336
|
+
validatorDstAddress: dstValoper,
|
|
337
|
+
amount: { denom: JAY_DENOM, amount: toMicro(amount) }
|
|
338
|
+
}
|
|
339
|
+
};
|
|
340
|
+
return this.broadcast([msg], memo, fee);
|
|
341
|
+
}
|
|
342
|
+
/** Claim staking rewards from one validator. */
|
|
343
|
+
async claimRewards(valoperAddress, memo = "", fee) {
|
|
344
|
+
const msg = {
|
|
345
|
+
typeUrl: "/cosmos.distribution.v1beta1.MsgWithdrawDelegatorReward",
|
|
346
|
+
value: { delegatorAddress: this.address, validatorAddress: valoperAddress }
|
|
347
|
+
};
|
|
348
|
+
return this.broadcast([msg], memo, fee);
|
|
349
|
+
}
|
|
350
|
+
/** Claim staking rewards from many validators in one tx. */
|
|
351
|
+
async claimAllRewards(valoperAddresses, memo = "", fee) {
|
|
352
|
+
const msgs = valoperAddresses.map((validatorAddress) => ({
|
|
353
|
+
typeUrl: "/cosmos.distribution.v1beta1.MsgWithdrawDelegatorReward",
|
|
354
|
+
value: { delegatorAddress: this.address, validatorAddress }
|
|
355
|
+
}));
|
|
356
|
+
return this.broadcast(msgs, memo, fee ?? defaultFee("400000"));
|
|
357
|
+
}
|
|
358
|
+
/** Withdraw a validator operator's accrued commission. */
|
|
359
|
+
async withdrawCommission(valoperAddress, memo = "", fee) {
|
|
360
|
+
const msg = {
|
|
361
|
+
typeUrl: "/cosmos.distribution.v1beta1.MsgWithdrawValidatorCommission",
|
|
362
|
+
value: { validatorAddress: valoperAddress }
|
|
363
|
+
};
|
|
364
|
+
return this.broadcast([msg], memo, fee);
|
|
365
|
+
}
|
|
366
|
+
/** Vote on a governance proposal (gov v1). */
|
|
367
|
+
async vote(proposalId, option, memo = "", fee) {
|
|
368
|
+
const value = VOTE_ENUM[option];
|
|
369
|
+
if (!value) throw new Error(`Invalid vote option: ${option}`);
|
|
370
|
+
const msg = {
|
|
371
|
+
typeUrl: "/cosmos.gov.v1.MsgVote",
|
|
372
|
+
value: {
|
|
373
|
+
proposalId: import_long.default.fromNumber(Number(proposalId)),
|
|
374
|
+
voter: this.address,
|
|
375
|
+
option: value,
|
|
376
|
+
metadata: ""
|
|
377
|
+
}
|
|
378
|
+
};
|
|
379
|
+
return this.broadcast([msg], memo, fee);
|
|
380
|
+
}
|
|
381
|
+
/** IBC transfer of JAY to another chain. */
|
|
382
|
+
async ibcTransfer(params, memo = "", fee) {
|
|
383
|
+
const { sourceChannel, receiver, amount, denom = JAY_DENOM, timeoutMinutes = 10 } = params;
|
|
384
|
+
const timeoutTimestamp = (Date.now() + timeoutMinutes * 60 * 1e3) * 1e6;
|
|
385
|
+
const msg = {
|
|
386
|
+
typeUrl: "/ibc.applications.transfer.v1.MsgTransfer",
|
|
387
|
+
value: {
|
|
388
|
+
sourcePort: "transfer",
|
|
389
|
+
sourceChannel,
|
|
390
|
+
token: { denom, amount: toMicro(amount) },
|
|
391
|
+
sender: this.address,
|
|
392
|
+
receiver,
|
|
393
|
+
timeoutHeight: { revisionNumber: "0", revisionHeight: "0" },
|
|
394
|
+
timeoutTimestamp: timeoutTimestamp.toString(),
|
|
395
|
+
memo
|
|
396
|
+
}
|
|
397
|
+
};
|
|
398
|
+
return this.broadcast([msg], memo, fee);
|
|
399
|
+
}
|
|
400
|
+
/** Disconnect the underlying client. */
|
|
401
|
+
disconnect() {
|
|
402
|
+
this.client.disconnect();
|
|
403
|
+
}
|
|
404
|
+
};
|
|
405
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
406
|
+
0 && (module.exports = {
|
|
407
|
+
DEFAULT_REST,
|
|
408
|
+
DEFAULT_RPC,
|
|
409
|
+
JAY_CHAIN_ID,
|
|
410
|
+
JAY_CHAIN_INFO,
|
|
411
|
+
JAY_CHAIN_NAME,
|
|
412
|
+
JAY_DECIMALS,
|
|
413
|
+
JAY_DENOM,
|
|
414
|
+
JAY_PREFIX,
|
|
415
|
+
JAY_SYMBOL,
|
|
416
|
+
JayClient,
|
|
417
|
+
JaySigningClient,
|
|
418
|
+
fromMicro,
|
|
419
|
+
isValidJayAddress,
|
|
420
|
+
isValidatorOperator,
|
|
421
|
+
jayCoin,
|
|
422
|
+
reEncodeAddress,
|
|
423
|
+
shortenAddress,
|
|
424
|
+
toMicro,
|
|
425
|
+
toValoper
|
|
426
|
+
});
|