Skip to content

Commit b2aeea6

Browse files
[skip ci] feat: progression
1 parent 0e57d39 commit b2aeea6

File tree

10 files changed

+512
-9
lines changed

10 files changed

+512
-9
lines changed

NEAR_ASSET_GENERATION_PLAN.md

Lines changed: 322 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,322 @@
1+
# NEAR Asset Generation Plan
2+
3+
## Overview
4+
5+
This document outlines the plan for adding NEAR Protocol asset generation to ShapeShift Web. NEAR is being integrated as a second-class citizen chain with native asset support and NEP-141 token support via CoinGecko.
6+
7+
## Current Understanding
8+
9+
### CAIP Identifiers (Already Added)
10+
- **Chain ID**: `near:mainnet` (CAIP-2)
11+
- **Native Asset ID**: `near:mainnet/slip44:397` (CAIP-19)
12+
- **Token Format**: `near:mainnet/nep141:{contract_account_id}` (CAIP-19)
13+
- **Namespace**: `Near: 'near'`
14+
- **Chain Reference**: `NearMainnet: 'mainnet'`
15+
- **Asset Reference**: `Near: '397'` (SLIP-44 coin type)
16+
- **Token Namespace**: `nep141` (NEP-141 fungible token standard)
17+
18+
### CoinGecko Support
19+
- **Platform ID**: `near-protocol`
20+
- CoinGecko indexes NEAR tokens via this platform
21+
- Token addresses are contract account IDs (e.g., `wrap.near`, `usdt.tether-token.near`)
22+
23+
### Swapper Support Status
24+
| Swapper | NEAR Support |
25+
|---------|-------------|
26+
| NEAR Intents | YES (this is our primary swapper for NEAR) |
27+
| THORChain | NO |
28+
| ChainFlip | NO |
29+
| 0x | NO |
30+
| 1inch | NO |
31+
| Portals | NO |
32+
| Relay | NO |
33+
| CowSwap | NO |
34+
35+
**Note**: NEAR Intents is the ONLY swapper that supports NEAR mainnet. This is fine since NEAR Intents is already integrated in ShapeShift.
36+
37+
---
38+
39+
## Asset Generation Implementation Plan
40+
41+
### Step 1: Add CoinGecko Adapter for NEAR
42+
43+
**File: `packages/caip/src/adapters/coingecko/index.ts`**
44+
45+
Add NEAR to the CoingeckoAssetPlatform enum:
46+
47+
```typescript
48+
export enum CoingeckoAssetPlatform {
49+
// ... existing platforms
50+
Near = 'near-protocol',
51+
}
52+
```
53+
54+
**File: `packages/caip/src/adapters/coingecko/utils.ts`**
55+
56+
Add chain ID to platform mapping:
57+
58+
```typescript
59+
import { nearChainId, CHAIN_NAMESPACE, CHAIN_REFERENCE } from '../../constants'
60+
61+
// In chainIdToCoingeckoAssetPlatform function
62+
case CHAIN_NAMESPACE.Near:
63+
switch (chainReference) {
64+
case CHAIN_REFERENCE.NearMainnet:
65+
return CoingeckoAssetPlatform.Near
66+
default:
67+
throw new Error(`chainReference '${chainReference}' not supported for NEAR namespace`)
68+
}
69+
```
70+
71+
### Step 2: Create NEAR Asset Generator
72+
73+
**File: `scripts/generateAssetData/near/index.ts`**
74+
75+
```typescript
76+
import { nearChainId } from '@shapeshiftoss/caip'
77+
import type { Asset } from '@shapeshiftoss/types'
78+
import { near, unfreeze } from '@shapeshiftoss/utils'
79+
80+
import * as coingecko from '../coingecko'
81+
82+
export const getAssets = async (): Promise<Asset[]> => {
83+
const assets = await coingecko.getAssets(nearChainId)
84+
85+
return [...assets, unfreeze(near)]
86+
}
87+
```
88+
89+
### Step 3: Add NEAR to CoinGecko Generator
90+
91+
**File: `scripts/generateAssetData/coingecko.ts`**
92+
93+
Import NEAR chain ID and base asset:
94+
95+
```typescript
96+
import {
97+
// ... existing imports
98+
nearChainId,
99+
} from '@shapeshiftoss/caip'
100+
101+
import {
102+
// ... existing imports
103+
near,
104+
} from '@shapeshiftoss/utils'
105+
```
106+
107+
Add NEAR case in the switch statement:
108+
109+
```typescript
110+
case nearChainId:
111+
return {
112+
assetNamespace: ASSET_NAMESPACE.nep141,
113+
category: adapters.chainIdToCoingeckoAssetPlatform(chainId),
114+
explorer: near.explorer,
115+
explorerAddressLink: near.explorerAddressLink,
116+
explorerTxLink: near.explorerTxLink,
117+
}
118+
```
119+
120+
### Step 4: Wire into Main Generator
121+
122+
**File: `scripts/generateAssetData/generateAssetData.ts`**
123+
124+
```typescript
125+
import * as near from './near'
126+
127+
// In generateAssetData function
128+
const nearAssets = await near.getAssets()
129+
130+
// Add to unfilteredAssetData array
131+
const unfilteredAssetData = [
132+
// ... existing assets
133+
...nearAssets,
134+
]
135+
```
136+
137+
### Step 5: Add NEAR Base Asset to Utils
138+
139+
**File: `packages/utils/src/assetData/baseAssets.ts`**
140+
141+
```typescript
142+
export const near: Asset = {
143+
assetId: nearAssetId,
144+
chainId: nearChainId,
145+
name: 'NEAR',
146+
precision: 24, // NEAR uses 24 decimals (yoctoNEAR)
147+
color: '#00C08B',
148+
icon: 'https://rawcdn.githack.com/trustwallet/assets/master/blockchains/near/info/logo.png',
149+
symbol: 'NEAR',
150+
explorer: 'https://nearblocks.io',
151+
explorerAddressLink: 'https://nearblocks.io/address/',
152+
explorerTxLink: 'https://nearblocks.io/txns/',
153+
relatedAssetKey: null,
154+
}
155+
```
156+
157+
**File: `packages/utils/src/assetData/index.ts`**
158+
159+
Export the near base asset.
160+
161+
---
162+
163+
## Testing Plan
164+
165+
### Phase 1: Test NEAR-Only Asset Generation Script
166+
167+
Create a minimal test script that ONLY generates NEAR assets to verify:
168+
1. CoinGecko adapter works for NEAR
169+
2. Token addresses are correctly formatted as `near:mainnet/nep141:{contract_id}`
170+
3. Asset metadata is properly fetched
171+
172+
**Test Script Location**: `scripts/generateAssetData/test-near-only.ts`
173+
174+
```typescript
175+
import { writeFile } from 'fs/promises'
176+
import { nearChainId, ASSET_NAMESPACE } from '@shapeshiftoss/caip'
177+
import * as adapters from '@shapeshiftoss/caip/src/adapters/coingecko'
178+
179+
// Minimal NEAR base asset for testing
180+
const nearBaseAsset = {
181+
assetId: 'near:mainnet/slip44:397',
182+
chainId: 'near:mainnet',
183+
name: 'NEAR',
184+
precision: 24,
185+
color: '#00C08B',
186+
icon: 'https://rawcdn.githack.com/trustwallet/assets/master/blockchains/near/info/logo.png',
187+
symbol: 'NEAR',
188+
explorer: 'https://nearblocks.io',
189+
explorerAddressLink: 'https://nearblocks.io/address/',
190+
explorerTxLink: 'https://nearblocks.io/txns/',
191+
}
192+
193+
async function testNearAssetGeneration() {
194+
console.log('Testing NEAR asset generation...')
195+
196+
// Test 1: Verify CoinGecko platform mapping
197+
console.log('\n1. Testing CoinGecko platform mapping...')
198+
const platform = adapters.chainIdToCoingeckoAssetPlatform(nearChainId)
199+
console.log(` Platform ID: ${platform}`)
200+
if (platform !== 'near-protocol') {
201+
throw new Error(`Expected 'near-protocol', got '${platform}'`)
202+
}
203+
console.log(' PASS')
204+
205+
// Test 2: Fetch NEAR tokens from CoinGecko
206+
console.log('\n2. Fetching NEAR tokens from CoinGecko...')
207+
const response = await fetch(
208+
'https://api.coingecko.com/api/v3/coins/list?include_platform=true'
209+
)
210+
const coins = await response.json()
211+
212+
const nearTokens = coins.filter(
213+
(coin: any) => coin.platforms && coin.platforms['near-protocol']
214+
)
215+
console.log(` Found ${nearTokens.length} NEAR tokens on CoinGecko`)
216+
217+
// Test 3: Format sample tokens
218+
console.log('\n3. Sample NEAR tokens:')
219+
const sampleTokens = nearTokens.slice(0, 5)
220+
for (const token of sampleTokens) {
221+
const contractAddress = token.platforms['near-protocol']
222+
const assetId = `near:mainnet/${ASSET_NAMESPACE.nep141}:${contractAddress}`
223+
console.log(` - ${token.name} (${token.symbol}): ${assetId}`)
224+
}
225+
226+
// Test 4: Generate test output
227+
console.log('\n4. Generating test output...')
228+
const testAssets = [
229+
nearBaseAsset,
230+
...sampleTokens.map((token: any) => ({
231+
assetId: `near:mainnet/nep141:${token.platforms['near-protocol']}`,
232+
chainId: nearChainId,
233+
name: token.name,
234+
symbol: token.symbol.toUpperCase(),
235+
precision: 24, // NEP-141 tokens typically use 24 decimals like NEAR
236+
color: '#00C08B',
237+
icon: '',
238+
explorer: 'https://nearblocks.io',
239+
explorerAddressLink: 'https://nearblocks.io/address/',
240+
explorerTxLink: 'https://nearblocks.io/txns/',
241+
})),
242+
]
243+
244+
await writeFile(
245+
'/tmp/near-test-assets.json',
246+
JSON.stringify(testAssets, null, 2)
247+
)
248+
console.log(' Wrote test output to /tmp/near-test-assets.json')
249+
250+
console.log('\n=== ALL TESTS PASSED ===')
251+
console.log(`Total NEAR assets: ${testAssets.length}`)
252+
return testAssets
253+
}
254+
255+
testNearAssetGeneration().catch(console.error)
256+
```
257+
258+
### Phase 2: Run Test Script
259+
260+
```bash
261+
# Run the NEAR-only test script
262+
npx tsx scripts/generateAssetData/test-near-only.ts
263+
264+
# Verify output
265+
cat /tmp/near-test-assets.json | head -50
266+
```
267+
268+
### Phase 3: Integration Testing
269+
270+
After test script passes:
271+
1. Add the actual NEAR generation code to the codebase
272+
2. Run `yarn generate:caip-adapters` to generate NEAR adapter JSON
273+
3. Do NOT run `yarn generate:asset-data` until confirmed by user
274+
4. Verify generated files look correct
275+
276+
---
277+
278+
## Files to Create/Modify
279+
280+
### New Files
281+
- [ ] `scripts/generateAssetData/near/index.ts` - NEAR asset generator
282+
- [ ] `scripts/generateAssetData/test-near-only.ts` - Test script (temporary)
283+
284+
### Modified Files
285+
- [x] `packages/caip/src/constants.ts` - NEAR CAIP constants (DONE)
286+
- [ ] `packages/caip/src/adapters/coingecko/index.ts` - Add Near platform enum
287+
- [ ] `packages/caip/src/adapters/coingecko/utils.ts` - Add chainId mapping
288+
- [ ] `packages/utils/src/assetData/baseAssets.ts` - Add NEAR base asset
289+
- [ ] `packages/utils/src/assetData/index.ts` - Export near base asset
290+
- [ ] `scripts/generateAssetData/coingecko.ts` - Add NEAR case
291+
- [ ] `scripts/generateAssetData/generateAssetData.ts` - Wire in NEAR generator
292+
293+
---
294+
295+
## Notes
296+
297+
### NEAR Precision
298+
- NEAR uses 24 decimal places (yoctoNEAR = 10^-24 NEAR)
299+
- This is different from most chains (ETH uses 18)
300+
- NEP-141 tokens can have varying decimals, but many use 24
301+
302+
### Token Contract Addresses
303+
- NEAR token addresses are human-readable account IDs, not hex addresses
304+
- Examples: `wrap.near`, `usdt.tether-token.near`, `aurora`
305+
- These go directly into the CAIP-19 format: `near:mainnet/nep141:wrap.near`
306+
307+
### No Zerion Needed for NEAR
308+
- Zerion API is used for related assets indexing on EVM chains
309+
- NEAR is not an EVM chain, so Zerion won't have NEAR data
310+
- CoinGecko is our primary source for NEAR token data
311+
312+
---
313+
314+
## Execution Order
315+
316+
1. **Create test script** and verify CoinGecko NEAR token fetching works
317+
2. **Add CoinGecko adapter** entries for NEAR
318+
3. **Add NEAR base asset** to utils
319+
4. **Create NEAR generator** module
320+
5. **Wire into main generator**
321+
6. **Run `yarn generate:caip-adapters`** (safe, just generates JSON mappings)
322+
7. **Verify output** before running full asset generation

0 commit comments

Comments
 (0)