@biochain/dweb-compat 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/.turbo/turbo-typecheck$colon$run.log +4 -0
- package/package.json +34 -0
- package/src/address.ts +79 -0
- package/src/bridge.ts +68 -0
- package/src/crypto-token.ts +196 -0
- package/src/index.ts +63 -0
- package/src/is-dweb.ts +33 -0
- package/src/noop.ts +145 -0
- package/src/plugins-stub.ts +36 -0
- package/src/signature.ts +195 -0
- package/src/tauri-stub.ts +12 -0
- package/src/types.ts +187 -0
- package/tsconfig.json +11 -0
package/package.json
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@biochain/dweb-compat",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "dweb-plaoc 到 KeyApp bio provider 的兼容适配器",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./src/index.ts",
|
|
7
|
+
"types": "./src/index.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./src/index.ts",
|
|
11
|
+
"import": "./src/index.ts"
|
|
12
|
+
},
|
|
13
|
+
"./is-dweb": {
|
|
14
|
+
"types": "./src/is-dweb.ts",
|
|
15
|
+
"import": "./src/is-dweb.ts"
|
|
16
|
+
},
|
|
17
|
+
"./plugins-stub": {
|
|
18
|
+
"types": "./src/plugins-stub.ts",
|
|
19
|
+
"import": "./src/plugins-stub.ts"
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"peerDependencies": {},
|
|
23
|
+
"devDependencies": {
|
|
24
|
+
"typescript": "^5.9.3",
|
|
25
|
+
"vitest": "^4.0.0"
|
|
26
|
+
},
|
|
27
|
+
"scripts": {
|
|
28
|
+
"typecheck": "tsc --noEmit",
|
|
29
|
+
"typecheck:run": "tsc --noEmit",
|
|
30
|
+
"test": "vitest",
|
|
31
|
+
"test:run": "vitest run",
|
|
32
|
+
"test:storybook": "echo 'SDK has no storybook'"
|
|
33
|
+
}
|
|
34
|
+
}
|
package/src/address.ts
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 地址授权适配
|
|
3
|
+
*
|
|
4
|
+
* 将 dweb 的 getWalleterAddresss 转换为 KeyApp 的 bio_requestAccounts
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { bioRequest } from './bridge'
|
|
8
|
+
import type { $WalletGetAddressResponse, $CHAIN_NAME } from './types'
|
|
9
|
+
|
|
10
|
+
/** KeyApp bio_accounts 返回的账户信息 */
|
|
11
|
+
interface BioAccountInfo {
|
|
12
|
+
address: string
|
|
13
|
+
chain: string
|
|
14
|
+
publicKey?: string
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* 获取钱包地址授权
|
|
19
|
+
*
|
|
20
|
+
* 对应 dweb 的 getWalleterAddresss(mmid)
|
|
21
|
+
* 转换为 KeyApp 的 bio_requestAccounts + bio_accounts
|
|
22
|
+
*/
|
|
23
|
+
export async function getWalleterAddresss(
|
|
24
|
+
_mmid: `${string}.dweb`
|
|
25
|
+
): Promise<$WalletGetAddressResponse | null> {
|
|
26
|
+
try {
|
|
27
|
+
// 1. 请求账户授权
|
|
28
|
+
const addresses = await bioRequest<string[]>('bio_requestAccounts')
|
|
29
|
+
|
|
30
|
+
if (!addresses || addresses.length === 0) {
|
|
31
|
+
return null
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// 2. 获取完整账户信息
|
|
35
|
+
let accounts: BioAccountInfo[]
|
|
36
|
+
try {
|
|
37
|
+
accounts = await bioRequest<BioAccountInfo[]>('bio_accounts')
|
|
38
|
+
} catch {
|
|
39
|
+
// 如果 bio_accounts 失败,使用地址构造基本信息
|
|
40
|
+
accounts = addresses.map(addr => ({ address: addr, chain: 'BFMeta' }))
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// 3. 转换为 dweb 格式
|
|
44
|
+
return accounts.map(acc => ({
|
|
45
|
+
name: '',
|
|
46
|
+
chainName: acc.chain as $CHAIN_NAME,
|
|
47
|
+
address: acc.address,
|
|
48
|
+
main: acc.address, // KeyApp 中 main 等于 address
|
|
49
|
+
publicKey: acc.publicKey || '',
|
|
50
|
+
privateKey: '', // 不暴露私钥
|
|
51
|
+
magic: '',
|
|
52
|
+
signMessage: '',
|
|
53
|
+
}))
|
|
54
|
+
} catch (error) {
|
|
55
|
+
console.error('[dweb-compat] getWalleterAddresss error:', error)
|
|
56
|
+
return null
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* 验证地址导入
|
|
62
|
+
*
|
|
63
|
+
* 对应 dweb 的 verifyAddressImport
|
|
64
|
+
*/
|
|
65
|
+
export async function verifyAddressImport(
|
|
66
|
+
_mmid: `${string}.dweb`,
|
|
67
|
+
opts: { address: string; message: string; chainName: $CHAIN_NAME }
|
|
68
|
+
): Promise<boolean> {
|
|
69
|
+
try {
|
|
70
|
+
const signature = await bioRequest<string>('bio_signMessage', {
|
|
71
|
+
address: opts.address,
|
|
72
|
+
message: opts.message,
|
|
73
|
+
chain: opts.chainName,
|
|
74
|
+
})
|
|
75
|
+
return typeof signature === 'string' && signature.length > 0
|
|
76
|
+
} catch {
|
|
77
|
+
return false
|
|
78
|
+
}
|
|
79
|
+
}
|
package/src/bridge.ts
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PostMessage Bridge - 与 KeyApp Bio Provider 通信
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
let requestId = 0
|
|
6
|
+
|
|
7
|
+
export interface BioResponse<T = unknown> {
|
|
8
|
+
success: boolean
|
|
9
|
+
result?: T
|
|
10
|
+
error?: { code: number; message: string }
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* 发送 bio_request 到 KeyApp 宿主
|
|
15
|
+
*/
|
|
16
|
+
export function bioRequest<T>(method: string, params?: unknown): Promise<T> {
|
|
17
|
+
return new Promise((resolve, reject) => {
|
|
18
|
+
const id = `dweb_compat_${++requestId}_${Date.now()}`
|
|
19
|
+
|
|
20
|
+
const handler = (event: MessageEvent) => {
|
|
21
|
+
const data = event.data
|
|
22
|
+
if (data?.type === 'bio_response' && data.id === id) {
|
|
23
|
+
window.removeEventListener('message', handler)
|
|
24
|
+
if (data.success) {
|
|
25
|
+
resolve(data.result as T)
|
|
26
|
+
} else {
|
|
27
|
+
const error = new Error(data.error?.message || 'Unknown error')
|
|
28
|
+
; (error as Error & { code?: number }).code = data.error?.code
|
|
29
|
+
reject(error)
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
window.addEventListener('message', handler)
|
|
35
|
+
|
|
36
|
+
// 发送请求到父窗口 (KeyApp)
|
|
37
|
+
const message = {
|
|
38
|
+
type: 'bio_request',
|
|
39
|
+
id,
|
|
40
|
+
method,
|
|
41
|
+
params: params !== undefined ? [params] : [],
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// 优先发送到 parent (iframe 模式),否则通过 self (web worker 或独立模式)
|
|
45
|
+
const target = window.parent !== window ? window.parent : window
|
|
46
|
+
target.postMessage(message, '*')
|
|
47
|
+
|
|
48
|
+
// 超时处理 (60 秒)
|
|
49
|
+
setTimeout(() => {
|
|
50
|
+
window.removeEventListener('message', handler)
|
|
51
|
+
reject(new Error(`Request timeout: ${method}`))
|
|
52
|
+
}, 60000)
|
|
53
|
+
})
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* 监听来自 KeyApp 的事件
|
|
58
|
+
*/
|
|
59
|
+
export function onBioEvent(event: string, callback: (...args: unknown[]) => void): () => void {
|
|
60
|
+
const handler = (e: MessageEvent) => {
|
|
61
|
+
if (e.data?.type === 'bio_event' && e.data.event === event) {
|
|
62
|
+
callback(...(e.data.args || []))
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
window.addEventListener('message', handler)
|
|
67
|
+
return () => window.removeEventListener('message', handler)
|
|
68
|
+
}
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Crypto Token API 封装
|
|
3
|
+
*
|
|
4
|
+
* 提供 Token 授权和加密操作的便捷函数
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { bioRequest } from './bridge'
|
|
8
|
+
|
|
9
|
+
// ==================== 类型定义 ====================
|
|
10
|
+
|
|
11
|
+
export type CryptoAction = 'asymmetricEncrypt' | 'sign'
|
|
12
|
+
export type TokenDuration = '5min' | '15min' | '1hour' | '1day'
|
|
13
|
+
|
|
14
|
+
export interface RequestCryptoTokenParams {
|
|
15
|
+
actions: CryptoAction[]
|
|
16
|
+
duration: TokenDuration
|
|
17
|
+
address: string
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface RequestCryptoTokenResponse {
|
|
21
|
+
tokenId: string
|
|
22
|
+
sessionSecret: string
|
|
23
|
+
expiresAt: number
|
|
24
|
+
grantedActions: CryptoAction[]
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface AsymmetricEncryptParams {
|
|
28
|
+
data: string
|
|
29
|
+
recipientPublicKey: string
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface SignParams {
|
|
33
|
+
data: string
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export interface CryptoExecuteResponse {
|
|
37
|
+
result: string
|
|
38
|
+
publicKey: string
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// ==================== Token 操作 ====================
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* 请求加密操作授权
|
|
45
|
+
*
|
|
46
|
+
* 用户需要输入手势密码确认授权
|
|
47
|
+
*
|
|
48
|
+
* @param actions 需要的操作权限
|
|
49
|
+
* @param duration 授权时长
|
|
50
|
+
* @param address 使用的地址
|
|
51
|
+
* @param chainId 链 ID(可选,用于 UI 显示)
|
|
52
|
+
*/
|
|
53
|
+
export async function requestCryptoToken(
|
|
54
|
+
actions: CryptoAction[],
|
|
55
|
+
duration: TokenDuration,
|
|
56
|
+
address: string,
|
|
57
|
+
chainId?: string
|
|
58
|
+
): Promise<RequestCryptoTokenResponse> {
|
|
59
|
+
return bioRequest<RequestCryptoTokenResponse>('bio_requestCryptoToken', {
|
|
60
|
+
actions,
|
|
61
|
+
duration,
|
|
62
|
+
address,
|
|
63
|
+
chainId,
|
|
64
|
+
})
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* 使用 Token 执行非对称加密
|
|
69
|
+
*/
|
|
70
|
+
export async function asymmetricEncrypt(
|
|
71
|
+
tokenId: string,
|
|
72
|
+
sessionSecret: string,
|
|
73
|
+
data: string,
|
|
74
|
+
recipientPublicKey: string
|
|
75
|
+
): Promise<CryptoExecuteResponse> {
|
|
76
|
+
return bioRequest<CryptoExecuteResponse>('bio_cryptoExecute', {
|
|
77
|
+
tokenId,
|
|
78
|
+
sessionSecret,
|
|
79
|
+
action: 'asymmetricEncrypt',
|
|
80
|
+
params: { data, recipientPublicKey },
|
|
81
|
+
})
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* 使用 Token 执行签名
|
|
86
|
+
*/
|
|
87
|
+
export async function signData(
|
|
88
|
+
tokenId: string,
|
|
89
|
+
sessionSecret: string,
|
|
90
|
+
data: string
|
|
91
|
+
): Promise<CryptoExecuteResponse> {
|
|
92
|
+
return bioRequest<CryptoExecuteResponse>('bio_cryptoExecute', {
|
|
93
|
+
tokenId,
|
|
94
|
+
sessionSecret,
|
|
95
|
+
action: 'sign',
|
|
96
|
+
params: { data },
|
|
97
|
+
})
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// ==================== RWA 登录便捷函数 ====================
|
|
101
|
+
|
|
102
|
+
export interface RwaLoginResult {
|
|
103
|
+
/** 钱包地址 */
|
|
104
|
+
address: string
|
|
105
|
+
/** 用户公钥 (Buffer) */
|
|
106
|
+
publicKey: Buffer
|
|
107
|
+
/** 加密的 signcode (Buffer) */
|
|
108
|
+
signcode: Buffer
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* 将各种格式的公钥转换为 hex 字符串
|
|
113
|
+
*/
|
|
114
|
+
function normalizeToHex(input: unknown): string {
|
|
115
|
+
if (typeof input === 'string') {
|
|
116
|
+
return input
|
|
117
|
+
}
|
|
118
|
+
// { type: 'Buffer', data: [...] } 格式
|
|
119
|
+
if (input && typeof input === 'object' && 'type' in input && 'data' in input) {
|
|
120
|
+
const bufferLike = input as { type: string; data: number[] }
|
|
121
|
+
if (bufferLike.type === 'Buffer' && Array.isArray(bufferLike.data)) {
|
|
122
|
+
return Buffer.from(bufferLike.data).toString('hex')
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
// Uint8Array 或 number[]
|
|
126
|
+
if (Array.isArray(input) || input instanceof Uint8Array) {
|
|
127
|
+
return Buffer.from(input as ArrayLike<number>).toString('hex')
|
|
128
|
+
}
|
|
129
|
+
// Buffer
|
|
130
|
+
if (Buffer.isBuffer(input)) {
|
|
131
|
+
return input.toString('hex')
|
|
132
|
+
}
|
|
133
|
+
throw new Error(`Invalid input format: ${typeof input}`)
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* RWA Hub 登录
|
|
138
|
+
*
|
|
139
|
+
* 封装了完整的 RWA 登录流程:
|
|
140
|
+
* 1. 获取钱包地址
|
|
141
|
+
* 2. 请求加密授权
|
|
142
|
+
* 3. 执行非对称加密生成 signcode
|
|
143
|
+
*
|
|
144
|
+
* @param systemPublicKey 系统公钥,支持 hex 字符串、Buffer 对象或字节数组
|
|
145
|
+
*/
|
|
146
|
+
export async function rwaLogin(
|
|
147
|
+
systemPublicKey: unknown
|
|
148
|
+
): Promise<RwaLoginResult> {
|
|
149
|
+
const systemPubKeyHex = normalizeToHex(systemPublicKey)
|
|
150
|
+
// BFMeta 相关链的所有可能名称
|
|
151
|
+
const BFMETA_CHAINS = ['bfmeta', 'bfchainv2', 'bioforest', 'bfmchain', 'bfchain']
|
|
152
|
+
|
|
153
|
+
// 1. 获取钱包地址(指定 BFMeta 链)
|
|
154
|
+
const accounts = await bioRequest<Array<{ address: string; chain: string; publicKey?: string }>>(
|
|
155
|
+
'bio_requestAccounts',
|
|
156
|
+
{ chain: 'bfmeta' } // RWA Hub 需要 BFMeta 链
|
|
157
|
+
)
|
|
158
|
+
|
|
159
|
+
if (!accounts || accounts.length === 0) {
|
|
160
|
+
throw new Error('No accounts available')
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// 找到 BFMeta 系列链的地址
|
|
164
|
+
const account = accounts.find(a => {
|
|
165
|
+
const chain = a.chain.toLowerCase()
|
|
166
|
+
return BFMETA_CHAINS.includes(chain)
|
|
167
|
+
})
|
|
168
|
+
if (!account) {
|
|
169
|
+
const chains = accounts.map(a => a.chain).join(', ')
|
|
170
|
+
throw new Error(`BFMeta account not found. Available chains: ${chains}`)
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// 2. 请求加密授权(用户输入手势密码)- 使用实际选中的链 ID
|
|
174
|
+
const { tokenId, sessionSecret } = await requestCryptoToken(
|
|
175
|
+
['asymmetricEncrypt'],
|
|
176
|
+
'5min',
|
|
177
|
+
account.address,
|
|
178
|
+
account.chain // 使用账户实际的链 ID
|
|
179
|
+
)
|
|
180
|
+
|
|
181
|
+
// 3. 执行非对称加密生成 signcode
|
|
182
|
+
const timestamp = Date.now().toString()
|
|
183
|
+
const { result, publicKey } = await asymmetricEncrypt(
|
|
184
|
+
tokenId,
|
|
185
|
+
sessionSecret,
|
|
186
|
+
timestamp,
|
|
187
|
+
systemPubKeyHex
|
|
188
|
+
)
|
|
189
|
+
|
|
190
|
+
// 返回 Buffer 格式,与 RWA 后端期望一致
|
|
191
|
+
return {
|
|
192
|
+
address: account.address,
|
|
193
|
+
publicKey: Buffer.from(publicKey, 'hex'),
|
|
194
|
+
signcode: Buffer.from(result, 'hex'),
|
|
195
|
+
}
|
|
196
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @biochain/dweb-compat
|
|
3
|
+
*
|
|
4
|
+
* dweb-plaoc 到 KeyApp bio provider 的兼容适配器
|
|
5
|
+
*
|
|
6
|
+
* 提供与 @nilai/dweb-plaoc 相同的 API 接口,
|
|
7
|
+
* 底层通过 postMessage 调用 KeyApp Bio Provider
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
// 核心功能
|
|
11
|
+
export { getWalleterAddresss, verifyAddressImport } from './address'
|
|
12
|
+
export { getExternalAppData } from './signature'
|
|
13
|
+
|
|
14
|
+
// Crypto Token API
|
|
15
|
+
export {
|
|
16
|
+
requestCryptoToken,
|
|
17
|
+
asymmetricEncrypt,
|
|
18
|
+
signData,
|
|
19
|
+
rwaLogin,
|
|
20
|
+
} from './crypto-token'
|
|
21
|
+
export type {
|
|
22
|
+
CryptoAction,
|
|
23
|
+
TokenDuration,
|
|
24
|
+
RequestCryptoTokenParams,
|
|
25
|
+
RequestCryptoTokenResponse,
|
|
26
|
+
AsymmetricEncryptParams,
|
|
27
|
+
SignParams,
|
|
28
|
+
CryptoExecuteResponse,
|
|
29
|
+
RwaLoginResult,
|
|
30
|
+
} from './crypto-token'
|
|
31
|
+
|
|
32
|
+
// 类型和常量
|
|
33
|
+
export {
|
|
34
|
+
$WALLET_PLAOC_PATH,
|
|
35
|
+
$WALLET_SIGNATURE_TYPE,
|
|
36
|
+
$WALLET_AUTHORIZE_ADDRESS_TYPE,
|
|
37
|
+
} from './types'
|
|
38
|
+
export type {
|
|
39
|
+
$CHAIN_NAME,
|
|
40
|
+
$WALLET_SIGNATURE_TRANSFER,
|
|
41
|
+
$WALLET_SIGNATURE_MESSAGE,
|
|
42
|
+
$WALLET_SIGNATURE_JSON,
|
|
43
|
+
$WALLET_SIGNATURE_DESTORY_ASSET,
|
|
44
|
+
$WALLET_SIGNATURE_PARAMETER,
|
|
45
|
+
$WalletGetAddressResponse,
|
|
46
|
+
$WalletSignatureResponse,
|
|
47
|
+
DwebAppConfig,
|
|
48
|
+
} from './types'
|
|
49
|
+
|
|
50
|
+
// 空操作函数
|
|
51
|
+
export {
|
|
52
|
+
canOpenUrl,
|
|
53
|
+
focusWindow,
|
|
54
|
+
appMaximize,
|
|
55
|
+
appVersionUpdate,
|
|
56
|
+
browserOpen,
|
|
57
|
+
restart,
|
|
58
|
+
getDwebAppDownUrl,
|
|
59
|
+
gotoDwebAppMarketDownLoad,
|
|
60
|
+
CorrecDwebAppLang,
|
|
61
|
+
listenerBackButton,
|
|
62
|
+
dwebAppConfig,
|
|
63
|
+
} from './noop'
|
package/src/is-dweb.ts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @plaoc/is-dweb 兼容层
|
|
3
|
+
*
|
|
4
|
+
* 在 miniapp 模式下返回 false
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* 判断是否在 dweb 环境
|
|
9
|
+
*/
|
|
10
|
+
export function isDweb(): boolean {
|
|
11
|
+
return false
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* 获取 dweb 大版本
|
|
16
|
+
*/
|
|
17
|
+
export function dwebTarget(): number {
|
|
18
|
+
return 0
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* 判断是否移动端
|
|
23
|
+
*/
|
|
24
|
+
export function isMobile(): boolean {
|
|
25
|
+
const nav = navigator as Navigator & { userAgentData?: { mobile: boolean } }
|
|
26
|
+
if (typeof navigator !== 'undefined' && nav.userAgentData) {
|
|
27
|
+
return !!nav.userAgentData.mobile
|
|
28
|
+
}
|
|
29
|
+
// 降级到 UA 检测
|
|
30
|
+
return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(
|
|
31
|
+
navigator.userAgent
|
|
32
|
+
)
|
|
33
|
+
}
|
package/src/noop.ts
ADDED
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 空操作函数
|
|
3
|
+
*
|
|
4
|
+
* 这些函数在 dweb 环境中有实际功能,但在 miniapp 中不需要
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type { DwebAppConfig } from './types'
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* 检查应用是否可打开
|
|
11
|
+
*
|
|
12
|
+
* 在 miniapp 模式下总是返回 true,因为钱包功能由宿主提供
|
|
13
|
+
*/
|
|
14
|
+
export function canOpenUrl(_mmid: `${string}.dweb`): Promise<{ success: boolean }> {
|
|
15
|
+
return Promise.resolve({ success: true })
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* 聚焦窗口
|
|
20
|
+
*
|
|
21
|
+
* 在 miniapp 模式下不需要此操作
|
|
22
|
+
*/
|
|
23
|
+
export function focusWindow(): Promise<Response> {
|
|
24
|
+
return Promise.resolve(new Response())
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* 窗口最大化
|
|
29
|
+
*
|
|
30
|
+
* 在 miniapp 模式下不需要此操作
|
|
31
|
+
*/
|
|
32
|
+
export function appMaximize(): Promise<Response> {
|
|
33
|
+
return Promise.resolve(new Response())
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* 版本更新
|
|
38
|
+
*
|
|
39
|
+
* 在 miniapp 模式下不支持
|
|
40
|
+
*/
|
|
41
|
+
export function appVersionUpdate(_metadataUrl: string): Window | null {
|
|
42
|
+
console.warn('[dweb-compat] appVersionUpdate is not supported in miniapp mode')
|
|
43
|
+
return null
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* 打开浏览器
|
|
48
|
+
*
|
|
49
|
+
* 在 miniapp 模式下使用 window.open
|
|
50
|
+
*/
|
|
51
|
+
export function browserOpen(url: string, target?: string): Promise<Window | null> {
|
|
52
|
+
return Promise.resolve(window.open(url, target || '_blank'))
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* 重启应用
|
|
57
|
+
*
|
|
58
|
+
* 在 miniapp 模式下刷新页面
|
|
59
|
+
*/
|
|
60
|
+
export function restart(): Promise<boolean> {
|
|
61
|
+
window.location.reload()
|
|
62
|
+
return Promise.resolve(true)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* 获取 Dweb App 下载地址
|
|
67
|
+
*
|
|
68
|
+
* 在 miniapp 模式下不需要下载钱包
|
|
69
|
+
*/
|
|
70
|
+
export function getDwebAppDownUrl(_info: {
|
|
71
|
+
marketUrl: string
|
|
72
|
+
name: string
|
|
73
|
+
applistJson: string
|
|
74
|
+
}): Promise<{ downloadUrl?: string; marketUrl?: string }> {
|
|
75
|
+
return Promise.resolve({})
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* 跳转到应用商城下载
|
|
80
|
+
*
|
|
81
|
+
* 在 miniapp 模式下不需要
|
|
82
|
+
*/
|
|
83
|
+
export function gotoDwebAppMarketDownLoad(_info: {
|
|
84
|
+
downloadUrl?: string
|
|
85
|
+
marketUrl?: string
|
|
86
|
+
}): Promise<Window | null> {
|
|
87
|
+
console.warn('[dweb-compat] gotoDwebAppMarketDownLoad is not supported in miniapp mode')
|
|
88
|
+
return Promise.resolve(null)
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* 矫正语言
|
|
93
|
+
*/
|
|
94
|
+
export function CorrecDwebAppLang(lang?: string): Promise<string> {
|
|
95
|
+
return Promise.resolve(lang || navigator.language)
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* 监听硬件返回按钮
|
|
100
|
+
*
|
|
101
|
+
* 在 miniapp 模式下使用浏览器历史 API
|
|
102
|
+
*/
|
|
103
|
+
export function listenerBackButton(callback: () => void): void {
|
|
104
|
+
window.addEventListener('popstate', callback)
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* DwebApp 配置
|
|
109
|
+
*
|
|
110
|
+
* 在 miniapp 模式下返回空配置
|
|
111
|
+
*/
|
|
112
|
+
export const dwebAppConfig = {
|
|
113
|
+
XPay(_alpha = false): DwebAppConfig {
|
|
114
|
+
return {
|
|
115
|
+
mmid: 'pay.nikola-x.com.dweb',
|
|
116
|
+
name: 'X Pay',
|
|
117
|
+
marketUrl: '',
|
|
118
|
+
applistJson: '',
|
|
119
|
+
}
|
|
120
|
+
},
|
|
121
|
+
BIWMeta(_alpha = false): DwebAppConfig {
|
|
122
|
+
return {
|
|
123
|
+
mmid: 'biw-meta.com.dweb',
|
|
124
|
+
name: 'BIWMeta',
|
|
125
|
+
marketUrl: '',
|
|
126
|
+
applistJson: '',
|
|
127
|
+
}
|
|
128
|
+
},
|
|
129
|
+
BFMPay(_alpha = false): DwebAppConfig {
|
|
130
|
+
return {
|
|
131
|
+
mmid: 'pay.bfmeta.info.dweb',
|
|
132
|
+
name: 'BFM Pay',
|
|
133
|
+
marketUrl: '',
|
|
134
|
+
applistJson: '',
|
|
135
|
+
}
|
|
136
|
+
},
|
|
137
|
+
NiLai(_alpha = false): DwebAppConfig {
|
|
138
|
+
return {
|
|
139
|
+
mmid: 'www.ni-lai.com.dweb',
|
|
140
|
+
name: 'NiLai',
|
|
141
|
+
marketUrl: '',
|
|
142
|
+
applistJson: '',
|
|
143
|
+
}
|
|
144
|
+
},
|
|
145
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @plaoc/plugins 存根
|
|
3
|
+
*
|
|
4
|
+
* 在 miniapp 模式下提供空实现
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
// 导出空的 dwebServiceWorker
|
|
8
|
+
export const dwebServiceWorker = {
|
|
9
|
+
fetch: () => Promise.reject(new Error('dwebServiceWorker is not available in miniapp mode')),
|
|
10
|
+
has: () => Promise.resolve(false),
|
|
11
|
+
close: () => Promise.resolve(false),
|
|
12
|
+
restart: () => Promise.resolve(false),
|
|
13
|
+
clearCache: () => Promise.resolve(),
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// 导出空的 windowPlugin
|
|
17
|
+
export const windowPlugin = {
|
|
18
|
+
maximize: () => Promise.resolve(new Response()),
|
|
19
|
+
focusWindow: () => Promise.resolve(new Response()),
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// 导出空的 configPlugin
|
|
23
|
+
export const configPlugin = {
|
|
24
|
+
getLang: () => Promise.resolve(navigator.language),
|
|
25
|
+
setLang: () => Promise.resolve(true),
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// 为了兼容性导出类型
|
|
29
|
+
export class WebSocketIpcBuilder {
|
|
30
|
+
constructor(_url: URL, _config: unknown) { }
|
|
31
|
+
get ipc() {
|
|
32
|
+
return {
|
|
33
|
+
request: () => Promise.reject(new Error('WebSocketIpc is not available in miniapp mode')),
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
package/src/signature.ts
ADDED
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 签名适配
|
|
3
|
+
*
|
|
4
|
+
* 将 dweb 的 getExternalAppData(signature, [...]) 转换为 KeyApp 的 bio_* 方法
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { bioRequest } from './bridge'
|
|
8
|
+
import {
|
|
9
|
+
$WALLET_PLAOC_PATH,
|
|
10
|
+
$WALLET_SIGNATURE_TYPE,
|
|
11
|
+
type $WALLET_SIGNATURE_PARAMETER,
|
|
12
|
+
type $WALLET_PLAOC_PATH_RESPONSE,
|
|
13
|
+
} from './types'
|
|
14
|
+
|
|
15
|
+
/** 转账响应 */
|
|
16
|
+
interface TransferResponse {
|
|
17
|
+
txId: string
|
|
18
|
+
transaction: string | object
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* 调用外部 App 获取数据
|
|
23
|
+
*
|
|
24
|
+
* 对应 dweb 的 getExternalAppData(mmid, pathname, search)
|
|
25
|
+
*/
|
|
26
|
+
export function getExternalAppData<T extends keyof $WALLET_PLAOC_PATH_RESPONSE>(
|
|
27
|
+
_mmid: `${string}.dweb`,
|
|
28
|
+
pathname: T,
|
|
29
|
+
params?: unknown
|
|
30
|
+
) {
|
|
31
|
+
const dataPromise = executeRequest<$WALLET_PLAOC_PATH_RESPONSE[T]>(pathname, params)
|
|
32
|
+
|
|
33
|
+
return {
|
|
34
|
+
getData: (): Promise<$WALLET_PLAOC_PATH_RESPONSE[T]> => dataPromise,
|
|
35
|
+
abort: (): void => {
|
|
36
|
+
// postMessage 请求不支持中止,这里只是兼容接口
|
|
37
|
+
console.warn('[dweb-compat] abort is not supported in miniapp mode')
|
|
38
|
+
},
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
async function executeRequest<T>(pathname: string, params: unknown): Promise<T> {
|
|
43
|
+
switch (pathname) {
|
|
44
|
+
case $WALLET_PLAOC_PATH.signature:
|
|
45
|
+
if (Array.isArray(params)) {
|
|
46
|
+
const results = await Promise.all(params.map(handleSignatureParam))
|
|
47
|
+
return results as T
|
|
48
|
+
}
|
|
49
|
+
throw new Error('Invalid signature params: expected array')
|
|
50
|
+
|
|
51
|
+
case $WALLET_PLAOC_PATH.getAddress:
|
|
52
|
+
// 地址请求走 address.ts 的 getWalleterAddresss
|
|
53
|
+
throw new Error('Use getWalleterAddresss for address requests')
|
|
54
|
+
|
|
55
|
+
case $WALLET_PLAOC_PATH.stakeAsset:
|
|
56
|
+
// 锻造功能暂不支持
|
|
57
|
+
throw new Error('stakeAsset is not supported in miniapp mode')
|
|
58
|
+
|
|
59
|
+
default:
|
|
60
|
+
throw new Error(`Unknown pathname: ${pathname}`)
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
async function handleSignatureParam(
|
|
65
|
+
param: $WALLET_SIGNATURE_PARAMETER
|
|
66
|
+
): Promise<TransferResponse | string | object | null> {
|
|
67
|
+
switch (param.type) {
|
|
68
|
+
case $WALLET_SIGNATURE_TYPE.transfer:
|
|
69
|
+
return handleTransfer(param)
|
|
70
|
+
|
|
71
|
+
case $WALLET_SIGNATURE_TYPE.message:
|
|
72
|
+
return handleMessage(param)
|
|
73
|
+
|
|
74
|
+
case $WALLET_SIGNATURE_TYPE.json:
|
|
75
|
+
return handleJsonSign(param)
|
|
76
|
+
|
|
77
|
+
case $WALLET_SIGNATURE_TYPE.destory:
|
|
78
|
+
return handleDestroy(param)
|
|
79
|
+
|
|
80
|
+
case $WALLET_SIGNATURE_TYPE.assetTypeBalance:
|
|
81
|
+
return handleGetBalance(param)
|
|
82
|
+
|
|
83
|
+
case $WALLET_SIGNATURE_TYPE.contract:
|
|
84
|
+
return handleContract(param)
|
|
85
|
+
|
|
86
|
+
default:
|
|
87
|
+
console.error('[dweb-compat] Unsupported signature type:', (param as { type: number }).type)
|
|
88
|
+
return { error: true, message: `Unsupported signature type: ${(param as { type: number }).type}` }
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
async function handleTransfer(param: {
|
|
93
|
+
chainName: string
|
|
94
|
+
senderAddress: string
|
|
95
|
+
receiveAddress: string
|
|
96
|
+
balance: string
|
|
97
|
+
assetType?: string
|
|
98
|
+
contractInfo?: { contractAddress: string; assetType: string; decimals: number | string }
|
|
99
|
+
}): Promise<TransferResponse> {
|
|
100
|
+
const result = await bioRequest<{ txHash: string; transaction?: object }>('bio_sendTransaction', {
|
|
101
|
+
from: param.senderAddress,
|
|
102
|
+
to: param.receiveAddress,
|
|
103
|
+
amount: param.balance,
|
|
104
|
+
chain: param.chainName,
|
|
105
|
+
asset: param.assetType,
|
|
106
|
+
contractInfo: param.contractInfo,
|
|
107
|
+
})
|
|
108
|
+
|
|
109
|
+
return {
|
|
110
|
+
txId: result.txHash,
|
|
111
|
+
transaction: result.transaction || result.txHash,
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
async function handleMessage(param: {
|
|
116
|
+
chainName: string
|
|
117
|
+
senderAddress: string
|
|
118
|
+
message: string
|
|
119
|
+
}): Promise<string> {
|
|
120
|
+
const signature = await bioRequest<string>('bio_signMessage', {
|
|
121
|
+
address: param.senderAddress,
|
|
122
|
+
message: param.message,
|
|
123
|
+
chain: param.chainName,
|
|
124
|
+
})
|
|
125
|
+
return signature
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
async function handleJsonSign(param: {
|
|
129
|
+
chainName: string
|
|
130
|
+
senderAddress: string
|
|
131
|
+
json: object
|
|
132
|
+
jsonInterpolation?: Array<{ path: string; index: 0 | 1 }>
|
|
133
|
+
}): Promise<TransferResponse> {
|
|
134
|
+
const result = await bioRequest<{ txId: string; transaction: object }>('bio_signTypedData', {
|
|
135
|
+
address: param.senderAddress,
|
|
136
|
+
data: param.json,
|
|
137
|
+
chain: param.chainName,
|
|
138
|
+
interpolation: param.jsonInterpolation,
|
|
139
|
+
})
|
|
140
|
+
return result
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
async function handleDestroy(param: {
|
|
144
|
+
chainName: string
|
|
145
|
+
senderAddress: string
|
|
146
|
+
assetType: string
|
|
147
|
+
destoryAmount: string
|
|
148
|
+
}): Promise<TransferResponse> {
|
|
149
|
+
const result = await bioRequest<{ txId: string; transaction: object }>('bio_destroyAsset', {
|
|
150
|
+
address: param.senderAddress,
|
|
151
|
+
chain: param.chainName,
|
|
152
|
+
assetType: param.assetType,
|
|
153
|
+
amount: param.destoryAmount,
|
|
154
|
+
})
|
|
155
|
+
return result
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
async function handleGetBalance(param: {
|
|
159
|
+
chainName: string
|
|
160
|
+
senderAddress: string
|
|
161
|
+
assetTypes: Array<{ assetType: string; contractAddress?: string }>
|
|
162
|
+
}): Promise<Record<string, { assetType: string; decimals: number; balance: string }>> {
|
|
163
|
+
const result = await bioRequest<Record<string, { assetType: string; decimals: number; balance: string }>>(
|
|
164
|
+
'bio_getBalance',
|
|
165
|
+
{
|
|
166
|
+
address: param.senderAddress,
|
|
167
|
+
chain: param.chainName,
|
|
168
|
+
assets: param.assetTypes,
|
|
169
|
+
}
|
|
170
|
+
)
|
|
171
|
+
return result
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
async function handleContract(param: {
|
|
175
|
+
chainName: string
|
|
176
|
+
senderAddress: string
|
|
177
|
+
receiveAddress: string
|
|
178
|
+
methods: string
|
|
179
|
+
params: unknown[]
|
|
180
|
+
data: string
|
|
181
|
+
amount?: string
|
|
182
|
+
}): Promise<TransferResponse> {
|
|
183
|
+
// 合约调用通过 bio_signTransaction
|
|
184
|
+
const result = await bioRequest<{ txId: string; signedTx: object }>('bio_signTransaction', {
|
|
185
|
+
from: param.senderAddress,
|
|
186
|
+
to: param.receiveAddress,
|
|
187
|
+
chain: param.chainName,
|
|
188
|
+
data: param.data,
|
|
189
|
+
value: param.amount || '0',
|
|
190
|
+
})
|
|
191
|
+
return {
|
|
192
|
+
txId: result.txId,
|
|
193
|
+
transaction: result.signedTx,
|
|
194
|
+
}
|
|
195
|
+
}
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* dweb-plaoc 类型定义
|
|
3
|
+
*
|
|
4
|
+
* 从 @nilai/dweb-plaoc/types.ts 复制并简化
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/** 链名称类型 */
|
|
8
|
+
export type $CHAIN_NAME =
|
|
9
|
+
| 'BFMeta'
|
|
10
|
+
| 'BFMetaV2'
|
|
11
|
+
| 'BIWMeta'
|
|
12
|
+
| 'Ethereum'
|
|
13
|
+
| 'Binance'
|
|
14
|
+
| 'Tron'
|
|
15
|
+
|
|
16
|
+
/** API 路径 */
|
|
17
|
+
export enum $WALLET_PLAOC_PATH {
|
|
18
|
+
/** 获取地址 */
|
|
19
|
+
getAddress = '/wallet/authorize/address',
|
|
20
|
+
/** 签名 */
|
|
21
|
+
signature = '/wallet/authorize/signature',
|
|
22
|
+
/** 锻造 */
|
|
23
|
+
stakeAsset = '/wallet/staking',
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/** 地址授权类型 */
|
|
27
|
+
export enum $WALLET_AUTHORIZE_ADDRESS_TYPE {
|
|
28
|
+
main = 'main',
|
|
29
|
+
network = 'network',
|
|
30
|
+
all = 'all',
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/** 签名类型 */
|
|
34
|
+
export enum $WALLET_SIGNATURE_TYPE {
|
|
35
|
+
/** 消息签名 */
|
|
36
|
+
message = 0,
|
|
37
|
+
/** 转账 */
|
|
38
|
+
transfer = 1,
|
|
39
|
+
/** 内链:凭证资产转移 */
|
|
40
|
+
bioforestChainCertificateTransfer = 2,
|
|
41
|
+
/** JSON 签名 */
|
|
42
|
+
json = 3,
|
|
43
|
+
/** 内链:同质化(非同质化)交易 */
|
|
44
|
+
ENTITY = 4,
|
|
45
|
+
/** 获取币种余额 */
|
|
46
|
+
assetTypeBalance = 5,
|
|
47
|
+
/** 调用智能合约 */
|
|
48
|
+
contract = 6,
|
|
49
|
+
/** 内链销毁 */
|
|
50
|
+
destory = 7,
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/** 消息签名参数 */
|
|
54
|
+
export interface $WALLET_SIGNATURE_MESSAGE {
|
|
55
|
+
type: typeof $WALLET_SIGNATURE_TYPE.message
|
|
56
|
+
chainName: $CHAIN_NAME
|
|
57
|
+
senderAddress: string
|
|
58
|
+
message: string
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/** 转账签名参数 */
|
|
62
|
+
export interface $WALLET_SIGNATURE_TRANSFER {
|
|
63
|
+
type: typeof $WALLET_SIGNATURE_TYPE.transfer
|
|
64
|
+
chainName: $CHAIN_NAME
|
|
65
|
+
assetType?: string
|
|
66
|
+
senderAddress: string
|
|
67
|
+
receiveAddress: string
|
|
68
|
+
privateKey?: string
|
|
69
|
+
balance: string
|
|
70
|
+
fee?: string
|
|
71
|
+
contractInfo?: {
|
|
72
|
+
contractAddress: string
|
|
73
|
+
assetType: string
|
|
74
|
+
decimals: number | string
|
|
75
|
+
}
|
|
76
|
+
remark?: Record<string, string>
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/** JSON 签名参数 */
|
|
80
|
+
export interface $WALLET_SIGNATURE_JSON {
|
|
81
|
+
type: typeof $WALLET_SIGNATURE_TYPE.json
|
|
82
|
+
chainName: $CHAIN_NAME
|
|
83
|
+
senderAddress: string
|
|
84
|
+
json: object
|
|
85
|
+
jsonInterpolation?: Array<{
|
|
86
|
+
path: string
|
|
87
|
+
index: 0 | 1
|
|
88
|
+
}>
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/** 销毁资产参数 */
|
|
92
|
+
export interface $WALLET_SIGNATURE_DESTORY_ASSET {
|
|
93
|
+
type: typeof $WALLET_SIGNATURE_TYPE.destory
|
|
94
|
+
chainName: $CHAIN_NAME
|
|
95
|
+
assetType: string
|
|
96
|
+
fee?: string
|
|
97
|
+
senderAddress: string
|
|
98
|
+
destoryAddress?: string
|
|
99
|
+
destoryAmount: string
|
|
100
|
+
remark?: Record<string, string>
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/** 获取余额参数 */
|
|
104
|
+
export interface $WALLET_ASSETTYPE_BALANCE {
|
|
105
|
+
type: typeof $WALLET_SIGNATURE_TYPE.assetTypeBalance
|
|
106
|
+
chainName: $CHAIN_NAME
|
|
107
|
+
senderAddress: string
|
|
108
|
+
assetTypes: Array<{
|
|
109
|
+
assetType: string
|
|
110
|
+
contractAddress?: string
|
|
111
|
+
}>
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/** 合约调用参数 */
|
|
115
|
+
export interface $WALLET_SIGNATURE_CONTRACT {
|
|
116
|
+
type: typeof $WALLET_SIGNATURE_TYPE.contract
|
|
117
|
+
chainName: $CHAIN_NAME
|
|
118
|
+
amount?: string
|
|
119
|
+
methods: string
|
|
120
|
+
params: unknown[]
|
|
121
|
+
senderAddress: string
|
|
122
|
+
receiveAddress: string
|
|
123
|
+
data: string
|
|
124
|
+
fee?: string
|
|
125
|
+
binanceGasInfo?: {
|
|
126
|
+
gasLimit: number | string
|
|
127
|
+
gasPrice: number | string
|
|
128
|
+
}
|
|
129
|
+
boradcast?: boolean
|
|
130
|
+
waitTrsInBlock?: boolean
|
|
131
|
+
waitTime?: number
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/** 签名参数联合类型 */
|
|
135
|
+
export type $WALLET_SIGNATURE_PARAMETER =
|
|
136
|
+
| $WALLET_SIGNATURE_MESSAGE
|
|
137
|
+
| $WALLET_SIGNATURE_DESTORY_ASSET
|
|
138
|
+
| $WALLET_SIGNATURE_TRANSFER
|
|
139
|
+
| $WALLET_SIGNATURE_JSON
|
|
140
|
+
| $WALLET_ASSETTYPE_BALANCE
|
|
141
|
+
| $WALLET_SIGNATURE_CONTRACT
|
|
142
|
+
|
|
143
|
+
/** 地址响应 */
|
|
144
|
+
export type $WalletGetAddressResponse = Array<{
|
|
145
|
+
name: string
|
|
146
|
+
chainName: $CHAIN_NAME
|
|
147
|
+
address: string
|
|
148
|
+
main: string
|
|
149
|
+
publicKey: string
|
|
150
|
+
privateKey: string
|
|
151
|
+
magic: string
|
|
152
|
+
signMessage?: string
|
|
153
|
+
}>
|
|
154
|
+
|
|
155
|
+
/** 签名响应 */
|
|
156
|
+
export type $WalletSignatureResponse = Array<
|
|
157
|
+
| string
|
|
158
|
+
| object
|
|
159
|
+
| { txId: string; transaction: string | object }
|
|
160
|
+
| { [assetType: string]: { assetType: string; decimals: number; balance: string; contracts?: string } }
|
|
161
|
+
| null
|
|
162
|
+
| { error: boolean; message: string }
|
|
163
|
+
>
|
|
164
|
+
|
|
165
|
+
/** API 响应类型映射 */
|
|
166
|
+
export type $WALLET_PLAOC_PATH_RESPONSE = {
|
|
167
|
+
[$WALLET_PLAOC_PATH.getAddress]: $WalletGetAddressResponse | null
|
|
168
|
+
[$WALLET_PLAOC_PATH.signature]: $WalletSignatureResponse | null
|
|
169
|
+
[$WALLET_PLAOC_PATH.stakeAsset]: {
|
|
170
|
+
address: string
|
|
171
|
+
orderId: string
|
|
172
|
+
stakeAssetType: string
|
|
173
|
+
stakeChainName: $CHAIN_NAME
|
|
174
|
+
stakeAmount: string
|
|
175
|
+
mintAssetType: string
|
|
176
|
+
mintChainName: $CHAIN_NAME
|
|
177
|
+
mintAmount: string
|
|
178
|
+
} | null
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/** DwebApp 配置 */
|
|
182
|
+
export interface DwebAppConfig {
|
|
183
|
+
mmid: `${string}.dweb`
|
|
184
|
+
name: string
|
|
185
|
+
marketUrl: string
|
|
186
|
+
applistJson: string
|
|
187
|
+
}
|