@vultisig/rujira 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.
Files changed (118) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/README.md +254 -0
  3. package/dist/assets/amount.d.ts +80 -0
  4. package/dist/assets/amount.d.ts.map +1 -0
  5. package/dist/assets/amount.js +186 -0
  6. package/dist/assets/asset.d.ts +43 -0
  7. package/dist/assets/asset.d.ts.map +1 -0
  8. package/dist/assets/asset.js +1 -0
  9. package/dist/assets/formats.d.ts +54 -0
  10. package/dist/assets/formats.d.ts.map +1 -0
  11. package/dist/assets/formats.js +164 -0
  12. package/dist/assets/index.d.ts +27 -0
  13. package/dist/assets/index.d.ts.map +1 -0
  14. package/dist/assets/index.js +45 -0
  15. package/dist/assets/registry.d.ts +37 -0
  16. package/dist/assets/registry.d.ts.map +1 -0
  17. package/dist/assets/registry.js +487 -0
  18. package/dist/assets/router.d.ts +44 -0
  19. package/dist/assets/router.d.ts.map +1 -0
  20. package/dist/assets/router.js +142 -0
  21. package/dist/client.d.ts +70 -0
  22. package/dist/client.d.ts.map +1 -0
  23. package/dist/client.js +250 -0
  24. package/dist/config/constants.d.ts +25 -0
  25. package/dist/config/constants.d.ts.map +1 -0
  26. package/dist/config/constants.js +36 -0
  27. package/dist/config.d.ts +41 -0
  28. package/dist/config.d.ts.map +1 -0
  29. package/dist/config.js +72 -0
  30. package/dist/discovery/discovery.d.ts +39 -0
  31. package/dist/discovery/discovery.d.ts.map +1 -0
  32. package/dist/discovery/discovery.js +250 -0
  33. package/dist/discovery/graphql-client.d.ts +46 -0
  34. package/dist/discovery/graphql-client.d.ts.map +1 -0
  35. package/dist/discovery/graphql-client.js +137 -0
  36. package/dist/discovery/index.d.ts +9 -0
  37. package/dist/discovery/index.d.ts.map +1 -0
  38. package/dist/discovery/index.js +7 -0
  39. package/dist/discovery/types.d.ts +62 -0
  40. package/dist/discovery/types.d.ts.map +1 -0
  41. package/dist/discovery/types.js +5 -0
  42. package/dist/easy-routes.d.ts +216 -0
  43. package/dist/easy-routes.d.ts.map +1 -0
  44. package/dist/easy-routes.js +241 -0
  45. package/dist/errors.d.ts +65 -0
  46. package/dist/errors.d.ts.map +1 -0
  47. package/dist/errors.js +184 -0
  48. package/dist/index.d.ts +46 -0
  49. package/dist/index.d.ts.map +1 -0
  50. package/dist/index.js +46 -0
  51. package/dist/modules/assets.d.ts +68 -0
  52. package/dist/modules/assets.d.ts.map +1 -0
  53. package/dist/modules/assets.js +127 -0
  54. package/dist/modules/deposit.d.ts +152 -0
  55. package/dist/modules/deposit.d.ts.map +1 -0
  56. package/dist/modules/deposit.js +233 -0
  57. package/dist/modules/index.d.ts +12 -0
  58. package/dist/modules/index.d.ts.map +1 -0
  59. package/dist/modules/index.js +9 -0
  60. package/dist/modules/orderbook.d.ts +80 -0
  61. package/dist/modules/orderbook.d.ts.map +1 -0
  62. package/dist/modules/orderbook.js +320 -0
  63. package/dist/modules/swap.d.ts +48 -0
  64. package/dist/modules/swap.d.ts.map +1 -0
  65. package/dist/modules/swap.js +318 -0
  66. package/dist/modules/withdraw.d.ts +46 -0
  67. package/dist/modules/withdraw.d.ts.map +1 -0
  68. package/dist/modules/withdraw.js +218 -0
  69. package/dist/services/fee-estimator.d.ts +14 -0
  70. package/dist/services/fee-estimator.d.ts.map +1 -0
  71. package/dist/services/fee-estimator.js +89 -0
  72. package/dist/services/price-impact.d.ts +11 -0
  73. package/dist/services/price-impact.d.ts.map +1 -0
  74. package/dist/services/price-impact.js +58 -0
  75. package/dist/signer/index.d.ts +3 -0
  76. package/dist/signer/index.d.ts.map +1 -0
  77. package/dist/signer/index.js +1 -0
  78. package/dist/signer/keysign-builder.d.ts +21 -0
  79. package/dist/signer/keysign-builder.d.ts.map +1 -0
  80. package/dist/signer/keysign-builder.js +106 -0
  81. package/dist/signer/types.d.ts +81 -0
  82. package/dist/signer/types.d.ts.map +1 -0
  83. package/dist/signer/types.js +8 -0
  84. package/dist/signer/vultisig-provider.d.ts +33 -0
  85. package/dist/signer/vultisig-provider.d.ts.map +1 -0
  86. package/dist/signer/vultisig-provider.js +242 -0
  87. package/dist/types.d.ts +375 -0
  88. package/dist/types.d.ts.map +1 -0
  89. package/dist/types.js +18 -0
  90. package/dist/utils/cache.d.ts +87 -0
  91. package/dist/utils/cache.d.ts.map +1 -0
  92. package/dist/utils/cache.js +124 -0
  93. package/dist/utils/denom-conversion.d.ts +47 -0
  94. package/dist/utils/denom-conversion.d.ts.map +1 -0
  95. package/dist/utils/denom-conversion.js +105 -0
  96. package/dist/utils/encoding.d.ts +17 -0
  97. package/dist/utils/encoding.d.ts.map +1 -0
  98. package/dist/utils/encoding.js +55 -0
  99. package/dist/utils/format.d.ts +108 -0
  100. package/dist/utils/format.d.ts.map +1 -0
  101. package/dist/utils/format.js +213 -0
  102. package/dist/utils/index.d.ts +10 -0
  103. package/dist/utils/index.d.ts.map +1 -0
  104. package/dist/utils/index.js +9 -0
  105. package/dist/utils/memo.d.ts +107 -0
  106. package/dist/utils/memo.d.ts.map +1 -0
  107. package/dist/utils/memo.js +190 -0
  108. package/dist/utils/rate-limiter.d.ts +38 -0
  109. package/dist/utils/rate-limiter.d.ts.map +1 -0
  110. package/dist/utils/rate-limiter.js +67 -0
  111. package/dist/utils/type-guards.d.ts +22 -0
  112. package/dist/utils/type-guards.d.ts.map +1 -0
  113. package/dist/utils/type-guards.js +27 -0
  114. package/dist/validation/address-validator.d.ts +15 -0
  115. package/dist/validation/address-validator.d.ts.map +1 -0
  116. package/dist/validation/address-validator.js +75 -0
  117. package/package.json +98 -0
  118. package/src/__tests__/live/README.md +47 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,23 @@
1
+ # @vultisig/rujira
2
+
3
+ ## 1.0.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#97](https://github.com/vultisig/vultisig-sdk/pull/97) [`75f441c`](https://github.com/vultisig/vultisig-sdk/commit/75f441cdf711e6ba04eed412dcf34002c5705144) Thanks [@bornslippynuxx](https://github.com/bornslippynuxx)! - Add Rujira DEX integration with FIN order book swaps, secured asset deposits/withdrawals, and CLI commands. New package: @vultisig/rujira for THORChain DEX operations (includes asset registry).
8
+
9
+ ### Patch Changes
10
+
11
+ - [#97](https://github.com/vultisig/vultisig-sdk/pull/97) [`e172aff`](https://github.com/vultisig/vultisig-sdk/commit/e172aff35aff86d182646a521dc1e3ac9e381f60) Thanks [@bornslippynuxx](https://github.com/bornslippynuxx)! - fix: address PR review bugs and safety issues
12
+ - Fix missing ChromeExtensionPolyfills import causing build failure
13
+ - Fix floating-point precision loss in CLI amount parsing for high-decimal tokens
14
+ - Fix BigInt crash on non-integer amount strings in swap validation
15
+ - Fix Number exponentiation precision loss in VaultSend formatAmount
16
+ - Use VaultError with error codes in chain validation instead of generic Error
17
+ - Add chainId mismatch validation in signAndBroadcast
18
+ - Add hex string input validation in hexDecode
19
+ - Guard against empty accounts array in client getAddress
20
+ - Use stricter bech32 THORChain address validator in deposit module
21
+
22
+ - Updated dependencies [[`bd543af`](https://github.com/vultisig/vultisig-sdk/commit/bd543af73a50a4ce431f38e3ed77511c4ef65ea7), [`74516fa`](https://github.com/vultisig/vultisig-sdk/commit/74516fae8dabd844c9e0793b932f6284ce9aa009), [`7ceab79`](https://github.com/vultisig/vultisig-sdk/commit/7ceab79e53986bfefa3f5d4cb5d25855572fbd3f), [`cd57d64`](https://github.com/vultisig/vultisig-sdk/commit/cd57d6482e08bd6172550ec4eea0e0233abd7f76), [`e172aff`](https://github.com/vultisig/vultisig-sdk/commit/e172aff35aff86d182646a521dc1e3ac9e381f60), [`ea1e8d5`](https://github.com/vultisig/vultisig-sdk/commit/ea1e8d5dd14a7273021577471e44719609f983ca), [`3f5fdcb`](https://github.com/vultisig/vultisig-sdk/commit/3f5fdcbfbe23aa287dfbcb38e9be6c904af9caf0), [`6c5c77c`](https://github.com/vultisig/vultisig-sdk/commit/6c5c77ceb49620f711285effee98b052e6aab1f8)]:
23
+ - @vultisig/sdk@0.5.0
package/README.md ADDED
@@ -0,0 +1,254 @@
1
+ # @vultisig/rujira
2
+
3
+ TypeScript SDK for interacting with **Rujira (FIN)** on THORChain.
4
+
5
+ It provides:
6
+ - FIN **swap** quotes + execution (CosmWasm)
7
+ - **Secured asset** ("synth-like") deposit helpers (inbound address + memo)
8
+ - **Withdrawal** helpers (THORChain `MsgDeposit` withdrawal flow)
9
+ - Route discovery + convenience **easy routes**
10
+
11
+ > Status: Early/alpha. APIs may change.
12
+
13
+ ---
14
+
15
+ ## Installation
16
+
17
+ ```bash
18
+ # npm
19
+ npm i @vultisig/rujira
20
+
21
+ # yarn
22
+ yarn add @vultisig/rujira
23
+
24
+ # pnpm
25
+ pnpm add @vultisig/rujira
26
+ ```
27
+
28
+ If you are working inside this monorepo, use the workspace dependency:
29
+
30
+ ```json
31
+ {
32
+ "dependencies": {
33
+ "@vultisig/rujira": "workspace:^"
34
+ }
35
+ }
36
+ ```
37
+
38
+ ---
39
+
40
+ ## Secured assets (what they are)
41
+
42
+ THORChain can custody L1 assets in inbound vaults and represent them on THORChain as **secured assets** (bank balances / denoms).
43
+
44
+ Typical flow:
45
+ 1. You send an L1 transfer (e.g. BTC) to a THORChain inbound address
46
+ 2. You include a memo that tells THORChain which THOR address should receive the secured asset
47
+ 3. THORChain credits your THOR address with the corresponding secured denom
48
+ 4. Those secured denoms can be swapped on FIN (Rujira orderbook DEX)
49
+ 5. You can withdraw back to L1 by broadcasting a THORChain `MsgDeposit` with a withdraw memo
50
+
51
+ Notes:
52
+ - THORChain secured balances are commonly stored with **8 decimals**.
53
+ - This package accepts **human-friendly asset notation** like `BTC.BTC` / `ETH.ETH` and maps to FIN denoms when available via the built-in asset registry.
54
+
55
+ ---
56
+
57
+ ## Quick start (read-only)
58
+
59
+ ```ts
60
+ import { RujiraClient } from '@vultisig/rujira'
61
+
62
+ const client = new RujiraClient({ network: 'mainnet' })
63
+ await client.connect()
64
+
65
+ // 1) Discover FIN routes / contracts
66
+ const quote = await client.swap.getQuote({
67
+ fromAsset: 'THOR.RUNE',
68
+ toAsset: 'BTC.BTC',
69
+ amount: '100000000', // base units (example)
70
+ })
71
+
72
+ console.log('Expected out:', quote.expectedOutput)
73
+ ```
74
+
75
+ ---
76
+
77
+ ## Quick start (with Vultisig signing)
78
+
79
+ To execute swaps/withdrawals you need a Cosmos signer. When using a Vultisig vault, use `VultisigRujiraProvider`.
80
+
81
+ ```ts
82
+ import { Vultisig } from '@vultisig/sdk'
83
+ import { RujiraClient, VultisigRujiraProvider } from '@vultisig/rujira'
84
+
85
+ // 1) Initialize Vultisig SDK + pick a vault
86
+ const sdk = new Vultisig({ /* ... */ })
87
+ await sdk.initialize()
88
+ const vault = await sdk.getActiveVault()
89
+ if (!vault) throw new Error('No active vault')
90
+
91
+ // 2) Create a Rujira client with a Vultisig-backed signer
92
+ const signer = new VultisigRujiraProvider(vault)
93
+ const client = new RujiraClient({ network: 'mainnet', signer })
94
+ await client.connect()
95
+
96
+ // 3) FIN swap (secured denoms on THORChain)
97
+ const thorDestination = await vault.address('THORChain')
98
+
99
+ const quote = await client.swap.getQuote({
100
+ fromAsset: 'BTC.BTC',
101
+ toAsset: 'ETH.ETH',
102
+ amount: '100000',
103
+ destination: thorDestination,
104
+ slippageBps: 100,
105
+ })
106
+
107
+ const swapResult = await client.swap.execute(quote, { slippageBps: 100 })
108
+ console.log('Swap tx hash:', swapResult.txHash)
109
+ ```
110
+
111
+ ---
112
+
113
+ ## Deposits (secure L1 → THORChain)
114
+
115
+ ### Get inbound address + memo
116
+
117
+ ```ts
118
+ import { RujiraClient } from '@vultisig/rujira'
119
+
120
+ const client = new RujiraClient({ network: 'mainnet' })
121
+ await client.connect()
122
+
123
+ const deposit = await client.deposit.prepare({
124
+ fromAsset: 'BTC.BTC',
125
+ amount: '100000', // base units; used for validation / dust threshold checks
126
+ thorAddress: 'thor1...',
127
+ })
128
+
129
+ console.log('Send to:', deposit.inboundAddress)
130
+ console.log('Memo:', deposit.memo)
131
+ ```
132
+
133
+ ### List all inbound addresses
134
+
135
+ ```ts
136
+ const inbound = await client.deposit.getInboundAddresses()
137
+ console.log(inbound.map(i => ({ chain: i.chain, address: i.address })))
138
+ ```
139
+
140
+ ### Check secured balances on THORChain
141
+
142
+ ```ts
143
+ const balances = await client.deposit.getBalances('thor1...')
144
+ console.log(balances)
145
+ ```
146
+
147
+ ---
148
+
149
+ ## Withdrawals (THORChain → L1)
150
+
151
+ Withdrawals are executed on THORChain via `MsgDeposit` with a withdraw memo. When using Vultisig, withdrawal execution requires a `VultisigRujiraProvider` (it exposes vault access for MsgDeposit signing).
152
+
153
+ ```ts
154
+ import { RujiraClient, VultisigRujiraProvider } from '@vultisig/rujira'
155
+
156
+ const client = new RujiraClient({ network: 'mainnet', signer: new VultisigRujiraProvider(vault) })
157
+ await client.connect()
158
+
159
+ const prepared = await client.withdraw.prepare({
160
+ asset: 'BTC.BTC',
161
+ amount: '100000',
162
+ l1Address: 'bc1...',
163
+ })
164
+
165
+ const result = await client.withdraw.execute(prepared)
166
+ console.log('Withdraw tx hash:', result.txHash)
167
+ ```
168
+
169
+ ---
170
+
171
+ ## Easy routes (convenience)
172
+
173
+ Use pre-defined routes to avoid thinking about pairs.
174
+
175
+ ```ts
176
+ import { EASY_ROUTES, listEasyRoutes, getRoutesSummary } from '@vultisig/rujira'
177
+
178
+ console.log(getRoutesSummary())
179
+ console.log(listEasyRoutes())
180
+
181
+ const route = EASY_ROUTES.RUNE_TO_USDC
182
+ ```
183
+
184
+ ---
185
+
186
+ ## API reference (high level)
187
+
188
+ ### `new RujiraClient(options)`
189
+
190
+ ```ts
191
+ export interface RujiraClientOptions {
192
+ config?: Partial<RujiraConfig>
193
+ signer?: RujiraSigner
194
+ rpcEndpoint?: string
195
+ contractCache?: {
196
+ load?: () => Promise<Record<string, string>> | Record<string, string>
197
+ save?: (finContracts: Record<string, string>) => Promise<void> | void
198
+ }
199
+ debug?: boolean
200
+ swapOptions?: RujiraSwapOptions
201
+ }
202
+ ```
203
+
204
+ Key methods:
205
+ - `connect()` / `disconnect()`
206
+ - `isConnected()` / `canSign()`
207
+ - `getAddress()`
208
+ - `getBalance(address, denom)` / `getAllBalances(address)`
209
+
210
+ Modules:
211
+ - `client.swap.getQuote(params)` / `client.swap.execute(quote, options)`
212
+ - `client.deposit.prepare(params)` / `client.deposit.getInboundAddresses()` / `client.deposit.getBalances(thorAddress)`
213
+ - `client.withdraw.prepare(params)` / `client.withdraw.execute(prepared)`
214
+
215
+ ### `VultisigRujiraProvider`
216
+
217
+ A Cosmos signer implementation that delegates signing to a Vultisig vault.
218
+
219
+ ```ts
220
+ import { VultisigRujiraProvider } from '@vultisig/rujira'
221
+
222
+ const signer = new VultisigRujiraProvider(vault /*, chainId? */)
223
+ ```
224
+
225
+ ---
226
+
227
+ ## GraphQL / discovery rate limits (optional)
228
+
229
+ Rujira contract discovery may use GraphQL. If you run into HTTP 429 rate limits, you can provide an API token to the **GraphQL client** used by discovery.
230
+
231
+ ```ts
232
+ import { RujiraDiscovery } from '@vultisig/rujira'
233
+
234
+ const discovery = new RujiraDiscovery({
235
+ network: 'mainnet',
236
+ graphql: { apiKey: process.env.RUJIRA_API_KEY },
237
+ })
238
+
239
+ const contracts = await discovery.discoverContracts()
240
+ ```
241
+
242
+ ---
243
+
244
+ ## Examples
245
+
246
+ See:
247
+ - `packages/rujira/examples/`
248
+ - `packages/rujira/docs/`
249
+
250
+ ---
251
+
252
+ ## License
253
+
254
+ MIT
@@ -0,0 +1,80 @@
1
+ import { Asset, Layer } from './asset.js';
2
+ /**
3
+ * Decimal conversion utilities
4
+ */
5
+ export declare function nativeToThorchain(amount: bigint, asset: Asset): bigint;
6
+ export declare function thorchainToNative(amount: bigint, asset: Asset): bigint;
7
+ export declare function thorchainToFin(amount: bigint, asset: Asset): bigint;
8
+ export declare function finToThorchain(amount: bigint, asset: Asset): bigint;
9
+ export declare function nativeToFin(amount: bigint, asset: Asset): bigint;
10
+ export declare function finToNative(amount: bigint, asset: Asset): bigint;
11
+ /**
12
+ * Amount class representing a value on a specific layer
13
+ */
14
+ export declare class Amount {
15
+ readonly asset: Asset;
16
+ readonly layer: Layer;
17
+ readonly raw: bigint;
18
+ constructor(asset: Asset, layer: Layer, raw: bigint);
19
+ /**
20
+ * Create Amount from human-readable string
21
+ */
22
+ static from(human: string, asset: Asset, layer: Layer): Amount;
23
+ /**
24
+ * Create Amount from raw bigint value
25
+ */
26
+ static fromRaw(raw: bigint, asset: Asset, layer: Layer): Amount;
27
+ /**
28
+ * Convert to specific layer
29
+ */
30
+ toLayer(target: Layer): Amount;
31
+ /**
32
+ * Convert to native layer
33
+ */
34
+ toNative(): Amount;
35
+ /**
36
+ * Convert to THORChain layer
37
+ */
38
+ toThorchain(): Amount;
39
+ /**
40
+ * Convert to FIN layer
41
+ */
42
+ toFin(): Amount;
43
+ /**
44
+ * Get human-readable representation
45
+ */
46
+ toHuman(precision?: number): string;
47
+ /**
48
+ * Get display string with asset name
49
+ */
50
+ toDisplay(precision?: number): string;
51
+ /**
52
+ * Get raw bigint value
53
+ */
54
+ toRaw(): bigint;
55
+ /**
56
+ * Add two amounts (must be same asset and layer)
57
+ */
58
+ add(other: Amount): Amount;
59
+ /**
60
+ * Subtract two amounts (must be same asset and layer)
61
+ */
62
+ subtract(other: Amount): Amount;
63
+ /**
64
+ * Multiply amount by a factor
65
+ */
66
+ multiply(factor: number): Amount;
67
+ /**
68
+ * Check if amount is zero
69
+ */
70
+ isZero(): boolean;
71
+ /**
72
+ * Check if amount is positive
73
+ */
74
+ isPositive(): boolean;
75
+ /**
76
+ * Compare with another amount
77
+ */
78
+ equals(other: Amount): boolean;
79
+ }
80
+ //# sourceMappingURL=amount.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"amount.d.ts","sourceRoot":"","sources":["../../src/assets/amount.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAEzC;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,MAAM,CAGtE;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,MAAM,CAGtE;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,MAAM,CAGnE;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,MAAM,CAGnE;AAED,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,MAAM,CAIhE;AAED,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,MAAM,CAIhE;AAED;;GAEG;AACH,qBAAa,MAAM;IACjB,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAA;IACrB,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAA;IACrB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;gBAER,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM;IAMnD;;OAEG;IACH,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,GAAG,MAAM;IAe9D;;OAEG;IACH,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,GAAG,MAAM;IAI/D;;OAEG;IACH,OAAO,CAAC,MAAM,EAAE,KAAK,GAAG,MAAM;IA0B9B;;OAEG;IACH,QAAQ,IAAI,MAAM;IAIlB;;OAEG;IACH,WAAW,IAAI,MAAM;IAIrB;;OAEG;IACH,KAAK,IAAI,MAAM;IAIf;;OAEG;IACH,OAAO,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM;IAoBnC;;OAEG;IACH,SAAS,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM;IAIrC;;OAEG;IACH,KAAK,IAAI,MAAM;IAIf;;OAEG;IACH,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;IAW1B;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;IAW/B;;OAEG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;IAKhC;;OAEG;IACH,MAAM,IAAI,OAAO;IAIjB;;OAEG;IACH,UAAU,IAAI,OAAO;IAIrB;;OAEG;IACH,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;CAG/B"}
@@ -0,0 +1,186 @@
1
+ /**
2
+ * Decimal conversion utilities
3
+ */
4
+ export function nativeToThorchain(amount, asset) {
5
+ const scale = asset.decimals.thorchain - asset.decimals.native;
6
+ return scale >= 0 ? amount * 10n ** BigInt(scale) : amount / 10n ** BigInt(-scale);
7
+ }
8
+ export function thorchainToNative(amount, asset) {
9
+ const scale = asset.decimals.native - asset.decimals.thorchain;
10
+ return scale >= 0 ? amount * 10n ** BigInt(scale) : amount / 10n ** BigInt(-scale);
11
+ }
12
+ export function thorchainToFin(amount, asset) {
13
+ const scale = asset.decimals.thorchain - asset.decimals.fin;
14
+ return amount / 10n ** BigInt(scale);
15
+ }
16
+ export function finToThorchain(amount, asset) {
17
+ const scale = asset.decimals.thorchain - asset.decimals.fin;
18
+ return amount * 10n ** BigInt(scale);
19
+ }
20
+ export function nativeToFin(amount, asset) {
21
+ // Convert through THORChain as intermediate
22
+ const thorchainAmount = nativeToThorchain(amount, asset);
23
+ return thorchainToFin(thorchainAmount, asset);
24
+ }
25
+ export function finToNative(amount, asset) {
26
+ // Convert through THORChain as intermediate
27
+ const thorchainAmount = finToThorchain(amount, asset);
28
+ return thorchainToNative(thorchainAmount, asset);
29
+ }
30
+ /**
31
+ * Amount class representing a value on a specific layer
32
+ */
33
+ export class Amount {
34
+ constructor(asset, layer, raw) {
35
+ this.asset = asset;
36
+ this.layer = layer;
37
+ this.raw = raw;
38
+ }
39
+ /**
40
+ * Create Amount from human-readable string
41
+ */
42
+ static from(human, asset, layer) {
43
+ const decimals = asset.decimals[layer];
44
+ const parts = human.split('.');
45
+ let raw = BigInt(parts[0]) * 10n ** BigInt(decimals);
46
+ if (parts[1]) {
47
+ const fractionalDigits = Math.min(parts[1].length, decimals);
48
+ const fractionalPart = parts[1].substring(0, fractionalDigits).padEnd(decimals, '0');
49
+ raw += BigInt(fractionalPart);
50
+ }
51
+ return new Amount(asset, layer, raw);
52
+ }
53
+ /**
54
+ * Create Amount from raw bigint value
55
+ */
56
+ static fromRaw(raw, asset, layer) {
57
+ return new Amount(asset, layer, raw);
58
+ }
59
+ /**
60
+ * Convert to specific layer
61
+ */
62
+ toLayer(target) {
63
+ if (this.layer === target) {
64
+ return this;
65
+ }
66
+ let targetRaw;
67
+ if (this.layer === 'native' && target === 'thorchain') {
68
+ targetRaw = nativeToThorchain(this.raw, this.asset);
69
+ }
70
+ else if (this.layer === 'thorchain' && target === 'native') {
71
+ targetRaw = thorchainToNative(this.raw, this.asset);
72
+ }
73
+ else if (this.layer === 'thorchain' && target === 'fin') {
74
+ targetRaw = thorchainToFin(this.raw, this.asset);
75
+ }
76
+ else if (this.layer === 'fin' && target === 'thorchain') {
77
+ targetRaw = finToThorchain(this.raw, this.asset);
78
+ }
79
+ else if (this.layer === 'native' && target === 'fin') {
80
+ targetRaw = nativeToFin(this.raw, this.asset);
81
+ }
82
+ else if (this.layer === 'fin' && target === 'native') {
83
+ targetRaw = finToNative(this.raw, this.asset);
84
+ }
85
+ else {
86
+ throw new Error(`Cannot convert from ${this.layer} to ${target}`);
87
+ }
88
+ return new Amount(this.asset, target, targetRaw);
89
+ }
90
+ /**
91
+ * Convert to native layer
92
+ */
93
+ toNative() {
94
+ return this.toLayer('native');
95
+ }
96
+ /**
97
+ * Convert to THORChain layer
98
+ */
99
+ toThorchain() {
100
+ return this.toLayer('thorchain');
101
+ }
102
+ /**
103
+ * Convert to FIN layer
104
+ */
105
+ toFin() {
106
+ return this.toLayer('fin');
107
+ }
108
+ /**
109
+ * Get human-readable representation
110
+ */
111
+ toHuman(precision) {
112
+ const decimals = this.asset.decimals[this.layer];
113
+ const divisor = 10n ** BigInt(decimals);
114
+ const wholePart = this.raw / divisor;
115
+ const fractionalPart = this.raw % divisor;
116
+ if (fractionalPart === 0n) {
117
+ return wholePart.toString();
118
+ }
119
+ const fractionalStr = fractionalPart.toString().padStart(decimals, '0');
120
+ const trimmed = precision !== undefined
121
+ ? fractionalStr.substring(0, precision).replace(/0+$/, '')
122
+ : fractionalStr.replace(/0+$/, '');
123
+ return trimmed.length > 0 ? `${wholePart}.${trimmed}` : wholePart.toString();
124
+ }
125
+ /**
126
+ * Get display string with asset name
127
+ */
128
+ toDisplay(precision) {
129
+ return `${this.toHuman(precision)} ${this.asset.id.toUpperCase()}`;
130
+ }
131
+ /**
132
+ * Get raw bigint value
133
+ */
134
+ toRaw() {
135
+ return this.raw;
136
+ }
137
+ /**
138
+ * Add two amounts (must be same asset and layer)
139
+ */
140
+ add(other) {
141
+ if (this.asset.id !== other.asset.id) {
142
+ throw new Error('Cannot add amounts of different assets');
143
+ }
144
+ if (this.layer !== other.layer) {
145
+ throw new Error('Cannot add amounts from different layers');
146
+ }
147
+ return new Amount(this.asset, this.layer, this.raw + other.raw);
148
+ }
149
+ /**
150
+ * Subtract two amounts (must be same asset and layer)
151
+ */
152
+ subtract(other) {
153
+ if (this.asset.id !== other.asset.id) {
154
+ throw new Error('Cannot subtract amounts of different assets');
155
+ }
156
+ if (this.layer !== other.layer) {
157
+ throw new Error('Cannot subtract amounts from different layers');
158
+ }
159
+ return new Amount(this.asset, this.layer, this.raw - other.raw);
160
+ }
161
+ /**
162
+ * Multiply amount by a factor
163
+ */
164
+ multiply(factor) {
165
+ const factorBigInt = (BigInt(Math.round(factor * 1000000)) * this.raw) / 1000000n;
166
+ return new Amount(this.asset, this.layer, factorBigInt);
167
+ }
168
+ /**
169
+ * Check if amount is zero
170
+ */
171
+ isZero() {
172
+ return this.raw === 0n;
173
+ }
174
+ /**
175
+ * Check if amount is positive
176
+ */
177
+ isPositive() {
178
+ return this.raw > 0n;
179
+ }
180
+ /**
181
+ * Compare with another amount
182
+ */
183
+ equals(other) {
184
+ return this.asset.id === other.asset.id && this.layer === other.layer && this.raw === other.raw;
185
+ }
186
+ }
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Asset interface representing a digital asset with multi-layer support
3
+ */
4
+ export type Asset = {
5
+ id: string;
6
+ name: string;
7
+ chain: string;
8
+ contract?: string;
9
+ decimals: {
10
+ native: number;
11
+ thorchain: number;
12
+ fin: number;
13
+ };
14
+ formats: {
15
+ l1: string;
16
+ thorchain: string;
17
+ fin: string;
18
+ };
19
+ };
20
+ /**
21
+ * Layer types supported by the assets package
22
+ */
23
+ export type Layer = 'native' | 'thorchain' | 'fin';
24
+ /**
25
+ * Quote interface for swap operations
26
+ */
27
+ export type Quote = {
28
+ path: 'thorchain-lp' | 'rujira-fin';
29
+ input: Amount;
30
+ output: Amount;
31
+ minimumOutput: Amount;
32
+ priceImpact: string;
33
+ fees: {
34
+ network: Amount;
35
+ protocol: Amount;
36
+ };
37
+ };
38
+ export type Amount = {
39
+ readonly asset: Asset;
40
+ readonly layer: Layer;
41
+ readonly raw: bigint;
42
+ };
43
+ //# sourceMappingURL=asset.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"asset.d.ts","sourceRoot":"","sources":["../../src/assets/asset.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,MAAM,KAAK,GAAG;IAClB,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE;QACR,MAAM,EAAE,MAAM,CAAA;QACd,SAAS,EAAE,MAAM,CAAA;QACjB,GAAG,EAAE,MAAM,CAAA;KACZ,CAAA;IACD,OAAO,EAAE;QACP,EAAE,EAAE,MAAM,CAAA;QACV,SAAS,EAAE,MAAM,CAAA;QACjB,GAAG,EAAE,MAAM,CAAA;KACZ,CAAA;CACF,CAAA;AAED;;GAEG;AACH,MAAM,MAAM,KAAK,GAAG,QAAQ,GAAG,WAAW,GAAG,KAAK,CAAA;AAElD;;GAEG;AACH,MAAM,MAAM,KAAK,GAAG;IAClB,IAAI,EAAE,cAAc,GAAG,YAAY,CAAA;IACnC,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;IACd,aAAa,EAAE,MAAM,CAAA;IACrB,WAAW,EAAE,MAAM,CAAA;IACnB,IAAI,EAAE;QACJ,OAAO,EAAE,MAAM,CAAA;QACf,QAAQ,EAAE,MAAM,CAAA;KACjB,CAAA;CACF,CAAA;AAGD,MAAM,MAAM,MAAM,GAAG;IACnB,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAA;IACrB,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAA;IACrB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;CACrB,CAAA"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,54 @@
1
+ import { Asset } from './asset.js';
2
+ /**
3
+ * Convert asset to THORChain format
4
+ */
5
+ export declare function toThorchainFormat(asset: Asset): string;
6
+ /**
7
+ * Convert asset to FIN format
8
+ */
9
+ export declare function toFinFormat(asset: Asset): string;
10
+ /**
11
+ * Convert asset to L1/native format
12
+ */
13
+ export declare function toL1Format(asset: Asset): string;
14
+ /**
15
+ * Parse asset identifier from any format
16
+ */
17
+ export declare function parseAsset(input: string): Asset | null;
18
+ /**
19
+ * Normalize THORChain pool name to standard format
20
+ */
21
+ export declare function normalizeThorchainPool(pool: string): string;
22
+ /**
23
+ * Normalize FIN format to lowercase with hyphens
24
+ */
25
+ export declare function normalizeFinFormat(format: string): string;
26
+ /**
27
+ * Extract chain from THORChain format
28
+ */
29
+ export declare function extractChainFromThorchain(thorchainFormat: string): string;
30
+ /**
31
+ * Extract symbol from THORChain format
32
+ */
33
+ export declare function extractSymbolFromThorchain(thorchainFormat: string): string;
34
+ /**
35
+ * Extract contract from THORChain format (if present)
36
+ */
37
+ export declare function extractContractFromThorchain(thorchainFormat: string): string | undefined;
38
+ /**
39
+ * Build THORChain format from components
40
+ */
41
+ export declare function buildThorchainFormat(chain: string, symbol: string, contract?: string): string;
42
+ /**
43
+ * Build FIN format from components
44
+ */
45
+ export declare function buildFinFormat(chain: string, symbol: string, contract?: string): string;
46
+ /**
47
+ * Convert between any two formats
48
+ */
49
+ export declare function convertFormat(input: string, targetFormat: 'l1' | 'thorchain' | 'fin'): string | null;
50
+ /**
51
+ * Detect format type of input string
52
+ */
53
+ export declare function detectFormat(input: string): 'l1' | 'thorchain' | 'fin' | 'unknown';
54
+ //# sourceMappingURL=formats.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formats.d.ts","sourceRoot":"","sources":["../../src/assets/formats.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAGlC;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,CAEtD;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,CAEhD;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,CAE/C;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,GAAG,IAAI,CAEtD;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAgB3D;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEzD;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,eAAe,EAAE,MAAM,GAAG,MAAM,CAqBzE;AAED;;GAEG;AACH,wBAAgB,0BAA0B,CAAC,eAAe,EAAE,MAAM,GAAG,MAAM,CAa1E;AAED;;GAEG;AACH,wBAAgB,4BAA4B,CAAC,eAAe,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAUxF;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAQ7F;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAQvF;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,IAAI,GAAG,WAAW,GAAG,KAAK,GAAG,MAAM,GAAG,IAAI,CAcpG;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,WAAW,GAAG,KAAK,GAAG,SAAS,CAyBlF"}