@mimicprotocol/lib-ts 0.0.1-rc.13 → 0.0.1-rc.15
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/package.json +1 -1
- package/src/chains/Sonic.ts +13 -0
- package/src/chains/index.ts +1 -0
- package/src/helpers/constants.ts +2 -1
- package/src/intents/Call.ts +3 -2
- package/src/intents/Intent.ts +64 -7
- package/src/intents/Swap.ts +3 -2
- package/src/intents/Transfer.ts +3 -2
- package/src/tokens/DenominationToken.ts +1 -1
- package/src/tokens/ERC20Token.ts +6 -3
- package/src/tokens/SPLToken.ts +113 -0
- package/src/tokens/Token.ts +1 -1
- package/src/types/Address.ts +2 -2
- package/src/types/ChainId.ts +2 -0
package/package.json
CHANGED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { ERC20Token } from '../tokens'
|
|
2
|
+
import { ChainId } from '../types'
|
|
3
|
+
|
|
4
|
+
/* eslint-disable no-secrets/no-secrets */
|
|
5
|
+
|
|
6
|
+
export namespace Sonic {
|
|
7
|
+
export const CHAIN_ID = ChainId.SONIC
|
|
8
|
+
export const SONIC = ERC20Token.native(CHAIN_ID)
|
|
9
|
+
export const USDC = ERC20Token.fromString('0x29219dd400f2Bf60E5a23d13Be72B486D4038894', CHAIN_ID, 6, 'USDC')
|
|
10
|
+
export const USDT = ERC20Token.fromString('0x6047828dc181963ba44974801ff68e538da5eaf9', CHAIN_ID, 6, 'USDT')
|
|
11
|
+
export const WETH = ERC20Token.fromString('0x50c42dEAcD8Fc9773493ED674b675bE577f2634b', CHAIN_ID, 18, 'WETH')
|
|
12
|
+
export const WSONIC = ERC20Token.fromString('0x039e2fB66102314Ce7b64Ce5Ce3E5183bc94aD38', CHAIN_ID, 18, 'WSONIC')
|
|
13
|
+
}
|
package/src/chains/index.ts
CHANGED
package/src/helpers/constants.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export const NULL_ADDRESS = '0x0000000000000000000000000000000000000000'
|
|
2
|
-
export const
|
|
2
|
+
export const EVM_NATIVE_ADDRESS = '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee'
|
|
3
|
+
export const SVM_NATIVE_ADDRESS = 'Nativeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee'
|
|
3
4
|
export const USD_ADDRESS = '0x0000000000000000000000000000000000000348'
|
|
4
5
|
|
|
5
6
|
export const STANDARD_DECIMALS: u8 = 18
|
package/src/intents/Call.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { TokenAmount } from '../tokens'
|
|
|
3
3
|
import { ChainId } from '../types'
|
|
4
4
|
import { Address, BigInt, Bytes } from '../types'
|
|
5
5
|
|
|
6
|
-
import { Intent, IntentBuilder, OperationType } from './Intent'
|
|
6
|
+
import { Intent, IntentBuilder, MaxFee, OperationType } from './Intent'
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* Builder for creating Call intents with contract call operations.
|
|
@@ -195,7 +195,8 @@ export class Call extends Intent {
|
|
|
195
195
|
deadline: BigInt | null = null,
|
|
196
196
|
nonce: string | null = null
|
|
197
197
|
) {
|
|
198
|
-
|
|
198
|
+
const fees: MaxFee[] = maxFees.map((fee: TokenAmount) => MaxFee.fromTokenAmount(fee))
|
|
199
|
+
super(OperationType.Call, chainId, fees, settler, user, deadline, nonce)
|
|
199
200
|
if (calls.length === 0) throw new Error('Call list cannot be empty')
|
|
200
201
|
if (maxFees.length == 0) throw new Error('At least a max fee must be specified')
|
|
201
202
|
|
package/src/intents/Intent.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { environment } from '../environment'
|
|
2
2
|
import { evm } from '../evm'
|
|
3
3
|
import { NULL_ADDRESS } from '../helpers'
|
|
4
|
-
import { TokenAmount } from '../tokens'
|
|
4
|
+
import { Token, TokenAmount } from '../tokens'
|
|
5
5
|
import { Address, BigInt, ChainId } from '../types'
|
|
6
6
|
|
|
7
7
|
export enum OperationType {
|
|
@@ -94,6 +94,65 @@ export abstract class IntentBuilder {
|
|
|
94
94
|
abstract build(): Intent
|
|
95
95
|
}
|
|
96
96
|
|
|
97
|
+
/**
|
|
98
|
+
* Represents an intent max fee.
|
|
99
|
+
* Specifies the token address and the max amount to be paid for the intent.
|
|
100
|
+
*/
|
|
101
|
+
@json
|
|
102
|
+
export class MaxFee {
|
|
103
|
+
token: string
|
|
104
|
+
amount: string
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Creates a MaxFee from a TokenAmount.
|
|
108
|
+
* @param tokenAmount - The token amount to be used as max fee
|
|
109
|
+
* @returns A new MaxFee instance
|
|
110
|
+
*/
|
|
111
|
+
static fromTokenAmount(tokenAmount: TokenAmount): MaxFee {
|
|
112
|
+
return new MaxFee(tokenAmount.token.address, tokenAmount.amount)
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Creates a MaxFee from a 32-bit integer amount.
|
|
117
|
+
* @param token - The max fee token
|
|
118
|
+
* @param amount - The max fee amount
|
|
119
|
+
* @returns A new MaxFee instance
|
|
120
|
+
*/
|
|
121
|
+
static fromI32(token: Token, amount: i32): MaxFee {
|
|
122
|
+
return this.fromTokenAmount(TokenAmount.fromI32(token, amount))
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Creates a MaxFee from a BigInt amount.
|
|
127
|
+
* @param token - The max fee token
|
|
128
|
+
* @param amount - The max fee amount in the token's smallest unit
|
|
129
|
+
* @returns A new MaxFee instance
|
|
130
|
+
*/
|
|
131
|
+
static fromBigInt(token: Token, amount: BigInt): MaxFee {
|
|
132
|
+
return this.fromTokenAmount(TokenAmount.fromBigInt(token, amount))
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Creates a MaxFee from a decimal string amount.
|
|
137
|
+
* @param token - The max fee token
|
|
138
|
+
* @param amount - The max fee amount as a decimal string
|
|
139
|
+
* @returns A new MaxFee instance
|
|
140
|
+
*/
|
|
141
|
+
static fromStringDecimal(token: Token, amount: string): MaxFee {
|
|
142
|
+
return this.fromTokenAmount(TokenAmount.fromStringDecimal(token, amount))
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Creates a new MaxFee instance.
|
|
147
|
+
* @param token - The max fee token address
|
|
148
|
+
* @param amount - The max fee amount
|
|
149
|
+
*/
|
|
150
|
+
constructor(token: Address, amount: BigInt) {
|
|
151
|
+
this.token = token.toString()
|
|
152
|
+
this.amount = amount.toString()
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
97
156
|
let INTENT_INDEX: u32 = 0
|
|
98
157
|
@json
|
|
99
158
|
export abstract class Intent {
|
|
@@ -102,14 +161,13 @@ export abstract class Intent {
|
|
|
102
161
|
public user: string
|
|
103
162
|
public deadline: string
|
|
104
163
|
public nonce: string
|
|
105
|
-
public
|
|
106
|
-
public maxFeeAmounts: string[]
|
|
164
|
+
public maxFees: MaxFee[]
|
|
107
165
|
|
|
108
166
|
/**
|
|
109
167
|
* Creates a new intent.
|
|
110
168
|
* @param op - The type of intent to be created
|
|
111
169
|
* @param chainId - The chain ID for fetch the settler
|
|
112
|
-
* @param maxFees - The list of max fees to pay for the intent
|
|
170
|
+
* @param maxFees - The list of max fees to pay for the intent (optional)
|
|
113
171
|
* @param settler - The settler address (optional)
|
|
114
172
|
* @param user - The user address (optional)
|
|
115
173
|
* @param deadline - The deadline timestamp (optional)
|
|
@@ -118,7 +176,7 @@ export abstract class Intent {
|
|
|
118
176
|
protected constructor(
|
|
119
177
|
op: OperationType,
|
|
120
178
|
chainId: ChainId,
|
|
121
|
-
maxFees:
|
|
179
|
+
maxFees: MaxFee[] | null,
|
|
122
180
|
settler: Address | null,
|
|
123
181
|
user: Address | null,
|
|
124
182
|
deadline: BigInt | null,
|
|
@@ -126,12 +184,11 @@ export abstract class Intent {
|
|
|
126
184
|
) {
|
|
127
185
|
const context = environment.getContext()
|
|
128
186
|
this.op = op
|
|
187
|
+
this.maxFees = maxFees || []
|
|
129
188
|
this.settler = settler ? settler.toString() : context.findSettler(chainId).toString()
|
|
130
189
|
this.deadline = deadline ? deadline.toString() : (context.timestamp / 1000 + DEFAULT_DEADLINE).toString()
|
|
131
190
|
this.user = user ? user.toString() : context.user.toString()
|
|
132
191
|
this.nonce = nonce ? nonce : evm.keccak(`${context.configSig}${context.timestamp}${++INTENT_INDEX}`)
|
|
133
|
-
this.maxFeeTokens = maxFees.map((fee: TokenAmount) => fee.token.address.toString())
|
|
134
|
-
this.maxFeeAmounts = maxFees.map((fee: TokenAmount) => fee.amount.toString())
|
|
135
192
|
|
|
136
193
|
if (!this.user || this.user == NULL_ADDRESS) throw new Error('A user must be specified')
|
|
137
194
|
if (!this.settler || this.settler == NULL_ADDRESS) throw new Error('A settler contract must be specified')
|
package/src/intents/Swap.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { environment } from '../environment'
|
|
|
2
2
|
import { ERC20Token, Token, TokenAmount } from '../tokens'
|
|
3
3
|
import { Address, BigInt, ChainId } from '../types'
|
|
4
4
|
|
|
5
|
-
import { Intent, IntentBuilder, OperationType } from './Intent'
|
|
5
|
+
import { Intent, IntentBuilder, MaxFee, OperationType } from './Intent'
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Builder for creating Swap intents with token exchange operations.
|
|
@@ -420,7 +420,8 @@ export class Swap extends Intent {
|
|
|
420
420
|
nonce: string | null = null,
|
|
421
421
|
maxFees: TokenAmount[] | null = null
|
|
422
422
|
) {
|
|
423
|
-
|
|
423
|
+
const fees: MaxFee[] = maxFees ? maxFees.map((fee: TokenAmount) => MaxFee.fromTokenAmount(fee)) : []
|
|
424
|
+
super(OperationType.Swap, sourceChain, fees, settler, user, deadline, nonce)
|
|
424
425
|
if (tokensIn.length === 0) throw new Error('TokenIn list cannot be empty')
|
|
425
426
|
if (tokensOut.length === 0) throw new Error('TokenOut list cannot be empty')
|
|
426
427
|
}
|
package/src/intents/Transfer.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { environment } from '../environment'
|
|
|
2
2
|
import { ERC20Token, Token, TokenAmount } from '../tokens'
|
|
3
3
|
import { Address, BigInt, ChainId } from '../types'
|
|
4
4
|
|
|
5
|
-
import { Intent, IntentBuilder, OperationType } from './Intent'
|
|
5
|
+
import { Intent, IntentBuilder, MaxFee, OperationType } from './Intent'
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Builder for creating Transfer intents with token transfer operations.
|
|
@@ -306,7 +306,8 @@ export class Transfer extends Intent {
|
|
|
306
306
|
deadline: BigInt | null = null,
|
|
307
307
|
nonce: string | null = null
|
|
308
308
|
) {
|
|
309
|
-
|
|
309
|
+
const fees: MaxFee[] = maxFees.map((fee: TokenAmount) => MaxFee.fromTokenAmount(fee))
|
|
310
|
+
super(OperationType.Transfer, chainId, fees, settler, user, deadline, nonce)
|
|
310
311
|
if (transfers.length === 0) throw new Error('Transfer list cannot be empty')
|
|
311
312
|
if (maxFees.length == 0) throw new Error('At least a max fee must be specified')
|
|
312
313
|
|
|
@@ -11,7 +11,7 @@ export class DenominationToken extends Token {
|
|
|
11
11
|
* @returns A new Denomination Token instance for USD
|
|
12
12
|
*/
|
|
13
13
|
static USD(): DenominationToken {
|
|
14
|
-
return new DenominationToken(Address.USD(),
|
|
14
|
+
return new DenominationToken(Address.USD(), 18, 'USD')
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
/**
|
package/src/tokens/ERC20Token.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { environment } from '../environment'
|
|
2
2
|
import { evm } from '../evm'
|
|
3
|
-
import {
|
|
3
|
+
import { EVM_NATIVE_ADDRESS } from '../helpers'
|
|
4
4
|
import { Address, ChainId, EvmDecodeParam } from '../types'
|
|
5
5
|
|
|
6
6
|
import { Token } from './Token'
|
|
@@ -27,9 +27,11 @@ export class ERC20Token extends Token {
|
|
|
27
27
|
case ChainId.BASE:
|
|
28
28
|
case ChainId.ARBITRUM:
|
|
29
29
|
case ChainId.OPTIMISM:
|
|
30
|
-
return ERC20Token.fromString(
|
|
30
|
+
return ERC20Token.fromString(EVM_NATIVE_ADDRESS, chainId, 18, 'ETH')
|
|
31
31
|
case ChainId.GNOSIS:
|
|
32
|
-
return ERC20Token.fromString(
|
|
32
|
+
return ERC20Token.fromString(EVM_NATIVE_ADDRESS, chainId, 18, 'xDAI')
|
|
33
|
+
case ChainId.SONIC:
|
|
34
|
+
return ERC20Token.fromString(EVM_NATIVE_ADDRESS, chainId, 18, 'SONIC')
|
|
33
35
|
default:
|
|
34
36
|
throw new Error(`Unsupported chainId: ${chainId}`)
|
|
35
37
|
}
|
|
@@ -88,6 +90,7 @@ export class ERC20Token extends Token {
|
|
|
88
90
|
symbol: string = ERC20Token.EMPTY_SYMBOL,
|
|
89
91
|
timestamp: Date | null = null
|
|
90
92
|
) {
|
|
93
|
+
if (!address.isEVM()) throw new Error(`Address ${address} must be an EVM address.`)
|
|
91
94
|
super(address, decimals, symbol)
|
|
92
95
|
this._chainId = chainId
|
|
93
96
|
this._timestamp = timestamp
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { SVM_NATIVE_ADDRESS } from '../helpers'
|
|
2
|
+
import { Address, ChainId } from '../types'
|
|
3
|
+
|
|
4
|
+
import { Token } from './Token'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Represents a token on a blockchain network including data like symbol, decimals, and address.
|
|
8
|
+
*/
|
|
9
|
+
export class SPLToken extends Token {
|
|
10
|
+
private _chainId: ChainId
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Creates a Token instance representing the native SOL token.
|
|
14
|
+
* @returns A new Token instance for the native token
|
|
15
|
+
*/
|
|
16
|
+
static native(): SPLToken {
|
|
17
|
+
return SPLToken.fromString(SVM_NATIVE_ADDRESS, 9, 'SOL')
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Creates a Token instance from an Address object.
|
|
22
|
+
* @param address - The token mint address
|
|
23
|
+
* @param decimals - Number of decimal places
|
|
24
|
+
* @param symbol - Token symbol
|
|
25
|
+
* @returns A new Token instance
|
|
26
|
+
*/
|
|
27
|
+
static fromAddress(address: Address, decimals: u8, symbol: string): SPLToken {
|
|
28
|
+
return new SPLToken(address, decimals, symbol)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Creates a Token instance from a string address.
|
|
33
|
+
* @param address - The token mint address as a base58 string
|
|
34
|
+
* @param decimals - Number of decimal places
|
|
35
|
+
* @param symbol - Token symbol
|
|
36
|
+
* @returns A new Token instance
|
|
37
|
+
*/
|
|
38
|
+
static fromString(address: string, decimals: u8, symbol: string): SPLToken {
|
|
39
|
+
return SPLToken.fromAddress(Address.fromString(address), decimals, symbol)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Creates a new Token instance.
|
|
44
|
+
* @param address - The token mint address
|
|
45
|
+
* @param decimals - Number of decimal places
|
|
46
|
+
* @param symbol - Token symbol
|
|
47
|
+
*/
|
|
48
|
+
constructor(address: Address, decimals: u8, symbol: string) {
|
|
49
|
+
if (!address.isSVM()) throw new Error(`Address ${address} must be an SVM address.`)
|
|
50
|
+
super(address, decimals, symbol)
|
|
51
|
+
this._chainId = ChainId.SOLANA_MAINNET
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Gets the blockchain network identifier where this token is deployed.
|
|
56
|
+
* This value is assigned during construction and remains constant throughout the token's lifecycle.
|
|
57
|
+
* @returns The `ChainId` representing the token's network.
|
|
58
|
+
*/
|
|
59
|
+
get chainId(): ChainId {
|
|
60
|
+
return this._chainId
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Gets the token's symbol (e.g., "SOL", "USDC").
|
|
65
|
+
* @returns A string containing the token symbol.
|
|
66
|
+
*/
|
|
67
|
+
get symbol(): string {
|
|
68
|
+
return this._symbol
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Gets the token's decimals (number of decimal places used).
|
|
73
|
+
* @returns A `u8` representing the number of decimals of the token.
|
|
74
|
+
*/
|
|
75
|
+
get decimals(): u8 {
|
|
76
|
+
return this._decimals
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Checks if this token is equal to another token.
|
|
81
|
+
* SPL Tokens are considered equal if they have the same address.
|
|
82
|
+
* @param other - The token to compare with
|
|
83
|
+
* @returns True if both tokens represent the same asset
|
|
84
|
+
*/
|
|
85
|
+
equals(other: Token): boolean {
|
|
86
|
+
return other instanceof SPLToken && super.equals(other)
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Checks if this token is the USD denomination.
|
|
91
|
+
* @returns False always
|
|
92
|
+
*/
|
|
93
|
+
isUSD(): boolean {
|
|
94
|
+
return false
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Checks if this token is the native token.
|
|
99
|
+
* @returns True if the token is the native token
|
|
100
|
+
*/
|
|
101
|
+
isNative(): boolean {
|
|
102
|
+
return this.equals(SPLToken.native())
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Checks if this token belongs to the requested chain.
|
|
107
|
+
* @param chain - The chain ID asking for
|
|
108
|
+
* @returns True if chains are equal
|
|
109
|
+
*/
|
|
110
|
+
hasChain(chain: ChainId): boolean {
|
|
111
|
+
return this.chainId === chain
|
|
112
|
+
}
|
|
113
|
+
}
|
package/src/tokens/Token.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { Address, ChainId } from '../types'
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Represents a token on a blockchain network including data like symbol, decimals, and address.
|
|
5
|
-
* Supports both ERC-20 and denomination tokens.
|
|
5
|
+
* Supports both ERC-20, SPL, and denomination tokens.
|
|
6
6
|
*/
|
|
7
7
|
export abstract class Token {
|
|
8
8
|
protected _symbol: string
|
package/src/types/Address.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
// Copyright (c) 2018 Graph Protocol, Inc. and contributors.
|
|
5
5
|
// Modified by Mimic Protocol, 2025.
|
|
6
6
|
|
|
7
|
-
import {
|
|
7
|
+
import { EVM_NATIVE_ADDRESS, isHex, USD_ADDRESS } from '../helpers'
|
|
8
8
|
|
|
9
9
|
import { ByteArray } from './ByteArray'
|
|
10
10
|
import { Bytes } from './Bytes'
|
|
@@ -32,7 +32,7 @@ export class Address extends Bytes {
|
|
|
32
32
|
* Returns the native address.
|
|
33
33
|
*/
|
|
34
34
|
static native(): Address {
|
|
35
|
-
return Address.fromString(
|
|
35
|
+
return Address.fromString(EVM_NATIVE_ADDRESS)
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
/**
|