@idos-network/kwil-infra 1.5.0 → 2.2.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/CHANGELOG.md +57 -0
- package/README.md +46 -1
- package/dist/actions/index.d.mts +2 -2
- package/dist/actions/index.mjs +1 -1370
- package/dist/actions/index.mjs.map +1 -1
- package/dist/facesign/index.d.mts +1 -1
- package/dist/facesign/index.mjs +1 -2
- package/dist/{facesign-signer-BC24j1eN.d.mts → facesign-signer-5I8juA7p.d.mts} +2 -1
- package/dist/facesign-signer-5I8juA7p.d.mts.map +1 -0
- package/dist/facesign-signer-z5T312uQ.mjs +2 -0
- package/dist/facesign-signer-z5T312uQ.mjs.map +1 -0
- package/dist/{index-iqkJfgWf.d.mts → index-Bqz6trCk.d.mts} +223 -136
- package/dist/index-Bqz6trCk.d.mts.map +1 -0
- package/dist/index.d.mts +2 -2
- package/dist/index.mjs +1 -429
- package/dist/index.mjs.map +1 -1
- package/dist/signature-verification/index.d.mts +3 -4
- package/dist/signature-verification/index.d.mts.map +1 -1
- package/dist/signature-verification/index.mjs +1 -134
- package/dist/signature-verification/index.mjs.map +1 -1
- package/dist/xrp/utils.d.mts +130 -20
- package/dist/xrp/utils.d.mts.map +1 -1
- package/dist/xrp/utils.mjs +1 -104
- package/dist/xrp/utils.mjs.map +1 -1
- package/dist/xrpl-credentials/index.d.mts +6 -7
- package/dist/xrpl-credentials/index.d.mts.map +1 -1
- package/dist/xrpl-credentials/index.mjs +1 -223
- package/dist/xrpl-credentials/index.mjs.map +1 -1
- package/package.json +7 -7
- package/src/actions/actions.test.ts +189 -0
- package/src/actions/actions.ts +368 -467
- package/src/actions/index.ts +38 -0
- package/src/create-kgw-authenticated-fetch.test.ts +377 -0
- package/src/create-kgw-authenticated-fetch.ts +321 -0
- package/src/create-kwil-client.ts +33 -10
- package/src/create-kwil-signer.test.ts +80 -0
- package/src/create-kwil-signer.ts +31 -5
- package/src/facesign/facesign-signer.test.ts +77 -0
- package/src/facesign/facesign-signer.ts +50 -2
- package/src/index.ts +2 -0
- package/src/mm-token/create-mm-token-kwil-signer.test.ts +148 -0
- package/src/mm-token/create-mm-token-kwil-signer.ts +166 -0
- package/src/near/create-near-wallet-kwil-signer.ts +1 -1
- package/src/signature-verification/index.test.ts +18 -0
- package/src/signature-verification/index.ts +7 -1
- package/src/wait-for-kwil-tx.test.ts +92 -0
- package/src/wait-for-kwil-tx.ts +111 -0
- package/tsdown.config.ts +1 -0
- package/dist/facesign-signer-BC24j1eN.d.mts.map +0 -1
- package/dist/facesign-signer-qzCcwunk.mjs +0 -244
- package/dist/facesign-signer-qzCcwunk.mjs.map +0 -1
- package/dist/index-iqkJfgWf.d.mts.map +0 -1
package/dist/index.mjs
CHANGED
|
@@ -1,430 +1,2 @@
|
|
|
1
|
-
import { actionSchema } from "./actions/index.mjs";
|
|
2
|
-
import { t as FaceSignSignerProvider } from "./facesign-signer-qzCcwunk.mjs";
|
|
3
|
-
import { getXrpPublicKey, getXrpTxHash, looksLikeXrpWallet } from "./xrp/utils.mjs";
|
|
4
|
-
import { KwilSigner, KwilSigner as KwilSigner$1, NodeKwil, WebKwil } from "@idos-network/kwil-js";
|
|
5
|
-
import invariant from "tiny-invariant";
|
|
6
|
-
import { base64Decode, binaryWriteUint16BE, borshSerialize, bs58Decode, bs58Encode, bytesConcat, hexDecode, hexEncode, sha256Hash, utf8Decode } from "@idos-network/utils/codecs";
|
|
7
|
-
import nacl from "tweetnacl";
|
|
8
|
-
//#region src/create-kwil-client.ts
|
|
9
|
-
/**
|
|
10
|
-
* A client for interacting with kwil with type-safe abstractions for `call` and `execute`.
|
|
11
|
-
* Has utility methods for creating actions and setting a signer.
|
|
12
|
-
*/
|
|
13
|
-
var KwilActionClient = class {
|
|
14
|
-
signer;
|
|
15
|
-
client;
|
|
16
|
-
constructor(client) {
|
|
17
|
-
this.client = client;
|
|
18
|
-
}
|
|
19
|
-
#createActionInputs(actionName, params = {}) {
|
|
20
|
-
if (!params || !Object.keys(params).length) return [];
|
|
21
|
-
return actionSchema[actionName].map(({ name }) => {
|
|
22
|
-
const value = params[name];
|
|
23
|
-
if (value === "" || value === 0) return value;
|
|
24
|
-
return value ?? null;
|
|
25
|
-
});
|
|
26
|
-
}
|
|
27
|
-
#actionTypes(actionName) {
|
|
28
|
-
return actionSchema[actionName].map((arg) => arg.type);
|
|
29
|
-
}
|
|
30
|
-
/**
|
|
31
|
-
* Calls an action on the kwil nodes. This similar to `GET` like request.
|
|
32
|
-
*/
|
|
33
|
-
async call(params, signer = this.signer) {
|
|
34
|
-
const action = {
|
|
35
|
-
name: params.name,
|
|
36
|
-
namespace: "main",
|
|
37
|
-
inputs: this.#createActionInputs(params.name, params.inputs),
|
|
38
|
-
types: this.#actionTypes(params.name)
|
|
39
|
-
};
|
|
40
|
-
return (await this.client.call(action, signer))?.data?.result;
|
|
41
|
-
}
|
|
42
|
-
/**
|
|
43
|
-
* Executes an action on the kwil nodes. This similar to `POST` like request.
|
|
44
|
-
*/
|
|
45
|
-
async execute(params, signer = this.signer, synchronous = true) {
|
|
46
|
-
invariant(signer, "Signer is not set, you must set it before executing an action");
|
|
47
|
-
const action = {
|
|
48
|
-
name: params.name,
|
|
49
|
-
namespace: "main",
|
|
50
|
-
description: params.description,
|
|
51
|
-
inputs: [this.#createActionInputs(params.name, params.inputs)],
|
|
52
|
-
types: this.#actionTypes(params.name)
|
|
53
|
-
};
|
|
54
|
-
return (await this.client.execute(action, signer, synchronous)).data?.tx_hash;
|
|
55
|
-
}
|
|
56
|
-
setSigner(signer) {
|
|
57
|
-
this.signer = signer;
|
|
58
|
-
}
|
|
59
|
-
};
|
|
60
|
-
const DEFAULT_TIMEOUT = 3e4;
|
|
61
|
-
const createKwilClient = (Cls) => async ({ nodeUrl: kwilProvider, chainId }) => {
|
|
62
|
-
const _kwil = new Cls({
|
|
63
|
-
kwilProvider,
|
|
64
|
-
chainId: ""
|
|
65
|
-
});
|
|
66
|
-
chainId ||= (await _kwil.chainInfo({ disableWarning: true })).data?.chain_id;
|
|
67
|
-
invariant(chainId, "Can't discover `chainId`. You must pass it explicitly.");
|
|
68
|
-
return new KwilActionClient(new Cls({
|
|
69
|
-
kwilProvider,
|
|
70
|
-
chainId,
|
|
71
|
-
timeout: DEFAULT_TIMEOUT
|
|
72
|
-
}));
|
|
73
|
-
};
|
|
74
|
-
/**
|
|
75
|
-
* Create a kwil client for node.js environment
|
|
76
|
-
*/
|
|
77
|
-
const createNodeKwilClient = createKwilClient(NodeKwil);
|
|
78
|
-
/**
|
|
79
|
-
* Create a kwil client for browser environment
|
|
80
|
-
*/
|
|
81
|
-
const createWebKwilClient = createKwilClient(WebKwil);
|
|
82
|
-
//#endregion
|
|
83
|
-
//#region src/near/get-config.ts
|
|
84
|
-
const NEAR_NETWORKS = {
|
|
85
|
-
mainnet: {
|
|
86
|
-
networkId: "mainnet",
|
|
87
|
-
nodeUrl: "https://rpc.mainnet.near.org"
|
|
88
|
-
},
|
|
89
|
-
testnet: {
|
|
90
|
-
networkId: "testnet",
|
|
91
|
-
nodeUrl: "https://rpc.testnet.near.org"
|
|
92
|
-
},
|
|
93
|
-
betanet: {
|
|
94
|
-
networkId: "betanet",
|
|
95
|
-
nodeUrl: "https://rpc.betanet.near.org"
|
|
96
|
-
},
|
|
97
|
-
shardnet: {
|
|
98
|
-
networkId: "shardnet",
|
|
99
|
-
nodeUrl: "https://rpc.shardnet.near.org"
|
|
100
|
-
}
|
|
101
|
-
};
|
|
102
|
-
const detectNearNetwork = (accountId) => {
|
|
103
|
-
if (accountId.endsWith(".near")) return "mainnet";
|
|
104
|
-
if (accountId.endsWith(".testnet")) return "testnet";
|
|
105
|
-
if (accountId.endsWith(".betanet")) return "betanet";
|
|
106
|
-
if (accountId.endsWith(".shardnet")) return "shardnet";
|
|
107
|
-
return "testnet";
|
|
108
|
-
};
|
|
109
|
-
const getNearConnectionConfig = (accountId) => {
|
|
110
|
-
const network = detectNearNetwork(accountId);
|
|
111
|
-
const networkConfig = NEAR_NETWORKS[network];
|
|
112
|
-
return {
|
|
113
|
-
networkId: networkConfig.networkId,
|
|
114
|
-
nodeUrl: networkConfig.nodeUrl
|
|
115
|
-
};
|
|
116
|
-
};
|
|
117
|
-
//#endregion
|
|
118
|
-
//#region src/near/create-near-wallet-kwil-signer.ts
|
|
119
|
-
const NEAR_WALLET_TYPES = [
|
|
120
|
-
"browser",
|
|
121
|
-
"injected",
|
|
122
|
-
"instant-link",
|
|
123
|
-
"hardware",
|
|
124
|
-
"bridge"
|
|
125
|
-
];
|
|
126
|
-
function looksLikeNearWallet(signer) {
|
|
127
|
-
return signer !== null && typeof signer === "object" && "id" in signer && "metadata" in signer && "type" in signer && typeof signer.type === "string" && NEAR_WALLET_TYPES.includes(signer.type);
|
|
128
|
-
}
|
|
129
|
-
var KwilNonce = class {
|
|
130
|
-
bytes;
|
|
131
|
-
constructor(length = 32) {
|
|
132
|
-
this.bytes = crypto.getRandomValues(new Uint8Array(length));
|
|
133
|
-
}
|
|
134
|
-
get clampUTF8() {
|
|
135
|
-
return this.bytes.map((byte) => byte & 127);
|
|
136
|
-
}
|
|
137
|
-
};
|
|
138
|
-
/**
|
|
139
|
-
* Creates a signer function that can be used to sign messages with a NEAR wallet
|
|
140
|
-
*/
|
|
141
|
-
function createNearWalletSigner(wallet, recipient) {
|
|
142
|
-
return async (message) => {
|
|
143
|
-
const messageString = typeof message === "string" ? message : utf8Decode(message);
|
|
144
|
-
if (!wallet.signMessage) throw new Error("Only wallets with signMessage are supported.");
|
|
145
|
-
const nonceSuggestion = Buffer.from(new KwilNonce(32).bytes);
|
|
146
|
-
const { nonce = nonceSuggestion, signature, callbackUrl } = await wallet.signMessage({
|
|
147
|
-
message: messageString,
|
|
148
|
-
recipient,
|
|
149
|
-
nonce: nonceSuggestion
|
|
150
|
-
});
|
|
151
|
-
const nep413BorshPayload = borshSerialize({ struct: {
|
|
152
|
-
tag: "u32",
|
|
153
|
-
message: "string",
|
|
154
|
-
nonce: { array: {
|
|
155
|
-
type: "u8",
|
|
156
|
-
len: 32
|
|
157
|
-
} },
|
|
158
|
-
recipient: "string",
|
|
159
|
-
callbackUrl: { option: "string" }
|
|
160
|
-
} }, {
|
|
161
|
-
tag: 2147484061,
|
|
162
|
-
message: messageString,
|
|
163
|
-
nonce: Array.from(nonce),
|
|
164
|
-
recipient,
|
|
165
|
-
callbackUrl
|
|
166
|
-
});
|
|
167
|
-
return bytesConcat(binaryWriteUint16BE(nep413BorshPayload.length), nep413BorshPayload, base64Decode(signature));
|
|
168
|
-
};
|
|
169
|
-
}
|
|
170
|
-
function implicitAddressFromPublicKey(publicKey) {
|
|
171
|
-
return hexEncode(bs58Decode(publicKey.replace(/^ed25519:/, "")));
|
|
172
|
-
}
|
|
173
|
-
async function getNearFullAccessPublicKeys(namedAddress) {
|
|
174
|
-
let connect;
|
|
175
|
-
try {
|
|
176
|
-
connect = (await import("near-api-js")).connect;
|
|
177
|
-
} catch (_e) {
|
|
178
|
-
throw new Error("Can't load near-api-js");
|
|
179
|
-
}
|
|
180
|
-
const connectionConfig = getNearConnectionConfig(namedAddress);
|
|
181
|
-
const nearConnection = await connect(connectionConfig);
|
|
182
|
-
try {
|
|
183
|
-
return (await nearConnection.connection.provider.query({
|
|
184
|
-
request_type: "view_access_key_list",
|
|
185
|
-
finality: "final",
|
|
186
|
-
account_id: namedAddress
|
|
187
|
-
})).keys.filter((element) => element.access_key.permission === "FullAccess")?.map((i) => i.public_key);
|
|
188
|
-
} catch {
|
|
189
|
-
return;
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
async function signNearMessage(wallet, message, recipient = "idos.network") {
|
|
193
|
-
return hexEncode(await createNearWalletSigner(wallet, recipient)(message));
|
|
194
|
-
}
|
|
195
|
-
async function createNearWalletKwilSigner(wallet, currentAddress, store, kwilClient, recipient = "idos.network") {
|
|
196
|
-
if (!wallet.signMessage) throw new Error("Only wallets with signMessage are supported.");
|
|
197
|
-
if (wallet.id === "my-near-wallet") {
|
|
198
|
-
const { accountId, signature, publicKey, error } = Object.fromEntries(new URLSearchParams(window.location.hash.slice(1)).entries());
|
|
199
|
-
if (signature) {
|
|
200
|
-
await store.set("signer-address", accountId);
|
|
201
|
-
await store.set("signer-public-key", publicKey);
|
|
202
|
-
}
|
|
203
|
-
const signMessageOriginal = wallet.signMessage.bind(wallet);
|
|
204
|
-
wallet.signMessage = async ({ message, recipient }) => {
|
|
205
|
-
if (error) return Promise.reject();
|
|
206
|
-
const lastMessage = await store.get("sign-last-message");
|
|
207
|
-
const lastNonce = await store.get("sign-last-nonce");
|
|
208
|
-
if (signature && message === lastMessage && lastNonce) {
|
|
209
|
-
const nonce = Buffer.from(lastNonce);
|
|
210
|
-
const callbackUrl = await store.get("sign-last-url");
|
|
211
|
-
return Promise.resolve({
|
|
212
|
-
accountId: currentAddress,
|
|
213
|
-
publicKey,
|
|
214
|
-
signature,
|
|
215
|
-
nonce,
|
|
216
|
-
message,
|
|
217
|
-
callbackUrl
|
|
218
|
-
});
|
|
219
|
-
}
|
|
220
|
-
const callbackUrl = window.location.href;
|
|
221
|
-
const nonce = Buffer.from(new KwilNonce(32).clampUTF8);
|
|
222
|
-
await store.set("sign-last-message", message);
|
|
223
|
-
await store.set("sign-last-nonce", Array.from(nonce));
|
|
224
|
-
await store.set("sign-last-url", callbackUrl);
|
|
225
|
-
signMessageOriginal({
|
|
226
|
-
message,
|
|
227
|
-
nonce,
|
|
228
|
-
recipient,
|
|
229
|
-
callbackUrl
|
|
230
|
-
});
|
|
231
|
-
return new Promise(() => ({}));
|
|
232
|
-
};
|
|
233
|
-
}
|
|
234
|
-
const storedAddress = await store.get("signer-address");
|
|
235
|
-
let publicKey = await store.get("signer-public-key");
|
|
236
|
-
if (storedAddress !== currentAddress || !publicKey) {
|
|
237
|
-
store.reset();
|
|
238
|
-
await kwilClient.client.auth.logoutKGW();
|
|
239
|
-
const message = "idOS authentication";
|
|
240
|
-
const nonce = Buffer.from(new KwilNonce(32).bytes);
|
|
241
|
-
const signResult = await wallet.signMessage({
|
|
242
|
-
message,
|
|
243
|
-
recipient,
|
|
244
|
-
nonce
|
|
245
|
-
});
|
|
246
|
-
if (!signResult) throw new Error("signMessage returned no result");
|
|
247
|
-
({publicKey} = signResult);
|
|
248
|
-
await store.set("signer-address", currentAddress);
|
|
249
|
-
await store.set("signer-public-key", publicKey);
|
|
250
|
-
}
|
|
251
|
-
return {
|
|
252
|
-
kwilSigner: new KwilSigner$1(createNearWalletSigner(wallet, recipient), implicitAddressFromPublicKey(publicKey), "nep413"),
|
|
253
|
-
publicKey
|
|
254
|
-
};
|
|
255
|
-
}
|
|
256
|
-
//#endregion
|
|
257
|
-
//#region src/near/nep413.ts
|
|
258
|
-
function kwilNep413Signer(recipient) {
|
|
259
|
-
return (keyPair) => async (messageBytes) => {
|
|
260
|
-
const message = utf8Decode(messageBytes);
|
|
261
|
-
const nonceLength = 32;
|
|
262
|
-
const nonce = crypto.getRandomValues(new Uint8Array(nonceLength));
|
|
263
|
-
const nep413BorschSchema = { struct: {
|
|
264
|
-
message: "string",
|
|
265
|
-
nonce: { array: {
|
|
266
|
-
type: "u8",
|
|
267
|
-
len: nonceLength
|
|
268
|
-
} },
|
|
269
|
-
recipient: "string",
|
|
270
|
-
callbackUrl: { option: "string" }
|
|
271
|
-
} };
|
|
272
|
-
const tag = 2147484061;
|
|
273
|
-
const { signature } = keyPair.sign(sha256Hash(bytesConcat(borshSerialize("u32", tag), borshSerialize(nep413BorschSchema, {
|
|
274
|
-
message,
|
|
275
|
-
nonce,
|
|
276
|
-
recipient
|
|
277
|
-
}))));
|
|
278
|
-
const kwilNep413BorshPayload = borshSerialize({ struct: {
|
|
279
|
-
tag: "u32",
|
|
280
|
-
...nep413BorschSchema.struct
|
|
281
|
-
} }, {
|
|
282
|
-
tag,
|
|
283
|
-
message,
|
|
284
|
-
nonce,
|
|
285
|
-
recipient
|
|
286
|
-
});
|
|
287
|
-
return bytesConcat(binaryWriteUint16BE(kwilNep413BorshPayload.length), kwilNep413BorshPayload, signature);
|
|
288
|
-
};
|
|
289
|
-
}
|
|
290
|
-
//#endregion
|
|
291
|
-
//#region src/xrp/signer.ts
|
|
292
|
-
async function createXrpKwilSigner(wallet, currentAddress, store, kwilClient, walletPublicKey) {
|
|
293
|
-
const storedAddress = await store.get("signer-address");
|
|
294
|
-
const storePublicKey = await store.get("signer-public-key");
|
|
295
|
-
if (storedAddress !== currentAddress || storePublicKey && storePublicKey !== walletPublicKey) try {
|
|
296
|
-
console.log("logoutKGW", kwilClient);
|
|
297
|
-
} catch (error) {
|
|
298
|
-
console.error("Failed to logout KGW:", error);
|
|
299
|
-
}
|
|
300
|
-
await store.set("signer-address", currentAddress);
|
|
301
|
-
await store.set("signer-public-key", walletPublicKey);
|
|
302
|
-
const signer = async (message) => {
|
|
303
|
-
const signature = await getXrpTxHash(message, wallet);
|
|
304
|
-
if (!signature) throw new Error("Failed to sign transaction with XRP");
|
|
305
|
-
return Buffer.from(signature, "hex");
|
|
306
|
-
};
|
|
307
|
-
return new KwilSigner$1(signer, walletPublicKey, "xrpl");
|
|
308
|
-
}
|
|
309
|
-
//#endregion
|
|
310
|
-
//#region src/create-kwil-signer.ts
|
|
311
|
-
/**
|
|
312
|
-
* Helper function to check if the given object is a `nacl.SignKeyPair`.
|
|
313
|
-
*/
|
|
314
|
-
function isNaclSignKeyPair(object) {
|
|
315
|
-
return object !== null && typeof object === "object" && "publicKey" in object && object.publicKey instanceof Uint8Array && object.publicKey.length === nacl.sign.publicKeyLength && "secretKey" in object && object.secretKey instanceof Uint8Array && object.secretKey.length === nacl.sign.secretKeyLength;
|
|
316
|
-
}
|
|
317
|
-
/**
|
|
318
|
-
* Helper function to check if the given object is a NEAR KeyPair.
|
|
319
|
-
*/
|
|
320
|
-
function isNearKeyPair(object) {
|
|
321
|
-
return object !== null && typeof object === "object" && "getPublicKey" in object && "sign" in object && typeof object.getPublicKey === "function" && typeof object.sign === "function";
|
|
322
|
-
}
|
|
323
|
-
/**
|
|
324
|
-
* Helper function to check if the given object is a Stellar Keypair.
|
|
325
|
-
*/
|
|
326
|
-
function isStellarKeyPair(object) {
|
|
327
|
-
return object !== null && typeof object === "object" && "publicKey" in object && "sign" in object && "canSign" in object && typeof object.publicKey === "function" && typeof object.sign === "function" && typeof object.canSign === "function";
|
|
328
|
-
}
|
|
329
|
-
function isCustomKwilSigner(object) {
|
|
330
|
-
return object !== null && typeof object === "object" && "publicAddress" in object && "signatureType" in object && "publicKey" in object && "signMessage" in object;
|
|
331
|
-
}
|
|
332
|
-
/**
|
|
333
|
-
* Helper function to check if the given object is a XRP KeyPair (Server key pairs only).
|
|
334
|
-
*/
|
|
335
|
-
function isXrplKeyPair(object) {
|
|
336
|
-
return !!object && typeof object === "object" && "privateKey" in object && "publicKey" in object;
|
|
337
|
-
}
|
|
338
|
-
/**
|
|
339
|
-
* Creates a `KwilSigner` and its associated `SignerAddress`.
|
|
340
|
-
*
|
|
341
|
-
* This function is explicitly marked as being for backend use only because it doesn't reset
|
|
342
|
-
* the KGW cookie when logging out and re-logging in with a different wallet.
|
|
343
|
-
*/
|
|
344
|
-
async function createServerKwilSigner(signer) {
|
|
345
|
-
if (isNaclSignKeyPair(signer)) return [new KwilSigner$1(async (msg) => nacl.sign.detached(msg, signer.secretKey), signer.publicKey, "ed25519"), implicitAddressFromPublicKey(bs58Encode(signer.publicKey))];
|
|
346
|
-
if (isNearKeyPair(signer)) {
|
|
347
|
-
const publicKey = implicitAddressFromPublicKey(signer.getPublicKey().toString());
|
|
348
|
-
return [new KwilSigner$1(kwilNep413Signer("idos-issuer")(signer), publicKey, "nep413"), publicKey];
|
|
349
|
-
}
|
|
350
|
-
if (isStellarKeyPair(signer)) {
|
|
351
|
-
const publicKeyString = signer.publicKey();
|
|
352
|
-
return [new KwilSigner$1(async (msg) => signer.sign(Buffer.from(msg)), signer.rawPublicKey(), "ed25519"), publicKeyString];
|
|
353
|
-
}
|
|
354
|
-
if (isXrplKeyPair(signer)) {
|
|
355
|
-
let xrpKeypair;
|
|
356
|
-
try {
|
|
357
|
-
xrpKeypair = await import("ripple-keypairs");
|
|
358
|
-
} catch (e) {
|
|
359
|
-
throw new Error("Can't load ripple-keypairs", { cause: e });
|
|
360
|
-
}
|
|
361
|
-
return [new KwilSigner$1(async (msg) => hexDecode(xrpKeypair.sign(hexEncode(msg), signer.privateKey)), signer.publicKey, "xrpl"), signer.publicKey];
|
|
362
|
-
}
|
|
363
|
-
if ("address" in signer) return [new KwilSigner$1(signer, signer.address), signer.address];
|
|
364
|
-
return ((_) => {
|
|
365
|
-
throw new Error("Invalid `signer` type");
|
|
366
|
-
})(signer);
|
|
367
|
-
}
|
|
368
|
-
async function createClientKwilSigner(store, kwilClient, wallet) {
|
|
369
|
-
if ("connect" in wallet && "address" in wallet) {
|
|
370
|
-
wallet = wallet;
|
|
371
|
-
const currentAddress = await wallet.getAddress();
|
|
372
|
-
if (await store.get("signer-address") !== currentAddress) {
|
|
373
|
-
store.set("signer-address", currentAddress);
|
|
374
|
-
try {
|
|
375
|
-
await kwilClient.client.auth.logoutKGW();
|
|
376
|
-
} catch (error) {
|
|
377
|
-
console.log("error logoutKGW", error);
|
|
378
|
-
}
|
|
379
|
-
}
|
|
380
|
-
return [
|
|
381
|
-
new KwilSigner$1(wallet, currentAddress),
|
|
382
|
-
currentAddress,
|
|
383
|
-
void 0,
|
|
384
|
-
"EVM"
|
|
385
|
-
];
|
|
386
|
-
}
|
|
387
|
-
if (looksLikeNearWallet(wallet)) {
|
|
388
|
-
const accounts = await wallet.getAccounts();
|
|
389
|
-
const { kwilSigner, publicKey } = await createNearWalletKwilSigner(wallet, accounts[0].accountId, store, kwilClient);
|
|
390
|
-
return [
|
|
391
|
-
kwilSigner,
|
|
392
|
-
accounts[0].accountId,
|
|
393
|
-
publicKey,
|
|
394
|
-
"NEAR"
|
|
395
|
-
];
|
|
396
|
-
}
|
|
397
|
-
if (looksLikeXrpWallet(wallet)) {
|
|
398
|
-
const { address: currentAddress, publicKey: walletPublicKey } = await getXrpPublicKey(wallet);
|
|
399
|
-
if (!currentAddress) throw new Error("Failed to get XRP address");
|
|
400
|
-
return [
|
|
401
|
-
await createXrpKwilSigner(wallet, currentAddress, store, kwilClient, walletPublicKey),
|
|
402
|
-
currentAddress,
|
|
403
|
-
walletPublicKey,
|
|
404
|
-
"XRPL"
|
|
405
|
-
];
|
|
406
|
-
}
|
|
407
|
-
if (isCustomKwilSigner(wallet) || wallet instanceof FaceSignSignerProvider) {
|
|
408
|
-
if (await store.get("signer-address") !== wallet.publicAddress) {
|
|
409
|
-
store.set("signer-address", wallet.publicAddress);
|
|
410
|
-
try {
|
|
411
|
-
await kwilClient.client.auth.logoutKGW();
|
|
412
|
-
} catch (error) {
|
|
413
|
-
console.log("error logoutKGW", error);
|
|
414
|
-
}
|
|
415
|
-
}
|
|
416
|
-
return [
|
|
417
|
-
new KwilSigner$1(async (msg) => wallet.signMessage(msg), wallet.publicAddress, "ed25519"),
|
|
418
|
-
wallet.publicAddress,
|
|
419
|
-
wallet.publicKey,
|
|
420
|
-
wallet.walletType
|
|
421
|
-
];
|
|
422
|
-
}
|
|
423
|
-
return ((_) => {
|
|
424
|
-
throw new Error("Invalid `signer` type");
|
|
425
|
-
})(wallet);
|
|
426
|
-
}
|
|
427
|
-
//#endregion
|
|
428
|
-
export { KwilActionClient, KwilSigner, createClientKwilSigner, createNodeKwilClient, createServerKwilSigner, createWebKwilClient, getNearFullAccessPublicKeys, implicitAddressFromPublicKey, signNearMessage };
|
|
429
|
-
|
|
1
|
+
import{actionSchema as e}from"./actions/index.mjs";import{t}from"./facesign-signer-z5T312uQ.mjs";import{getXrpPublicKey as n,getXrpTxHash as r,looksLikeXrpWallet as i}from"./xrp/utils.mjs";import{KwilSigner as a,KwilSigner as o,NodeKwil as s,WebKwil as c}from"@idos-network/kwil-js";import l from"tiny-invariant";import{BlobGateway as u,createUkycContentUri as d}from"@idos-network/utils/blob-gateway";import{base64Decode as f,base64UrlDecode as p,base64UrlEncode as m,binaryWriteUint16BE as h,borshSerialize as g,bs58Decode as ee,bs58Encode as _,bytesConcat as v,hexDecode as y,hexEncode as b,sha256Hash as te,utf8Decode as x,utf8Encode as S}from"@idos-network/utils/codecs";import C from"tweetnacl";var w=class extends Error{txHash;code;log;height;name=`KwilTxFailedError`;constructor(e,t,n,r){super(`Kwil transaction ${e} failed at height ${r} (code ${t}): ${n}`),this.txHash=e,this.code=t,this.log=n,this.height=r}},T=class extends Error{txHash;deadlineMs;name=`KwilTxPollTimeoutError`;constructor(e,t,n){let r=n?.cause instanceof Error?n.cause.message:n?.cause==null?void 0:String(n.cause);super(r?`Timed out after ${t}ms waiting for Kwil transaction ${e}: last error: ${r}`:`Timed out after ${t}ms waiting for Kwil transaction ${e}`,n?.cause===void 0?void 0:{cause:n.cause}),this.txHash=e,this.deadlineMs=t}};function E(e){return new Promise(t=>setTimeout(t,e))}function D(e){return Math.min(e*1.5,2e3)}function O(e){return e+Math.floor(Math.random()*101)}function ne(e){return e.height>0}async function re(e,t,n=9e4){let r=Date.now()+n,i=300,a;for(;Date.now()<r;){let n;try{n=(await e(t)).data}catch(e){a=e}if(n&&ne(n)){if(n.tx_result.code!==0)throw new w(t,n.tx_result.code,n.tx_result.log,n.height);return}let o=O(i),s=r-Date.now();if(s<=0)break;await E(Math.min(o,s)),i=D(i)}throw new T(t,n,a===void 0?void 0:{cause:a})}var k=class{signer;client;constructor(e){this.client=e}#e(t,n={}){return!n||!Object.keys(n).length?[]:e[t].map(({name:e})=>{let t=n[e];return t===``||t===0?t:t??null})}#t(t){return e[t].map(e=>e.type)}async call(e,t=this.signer){let n={name:e.name,namespace:`main`,inputs:this.#e(e.name,e.inputs),types:this.#t(e.name)};return(await this.client.call(n,t))?.data?.result}async execute(e,t=this.signer,n=!0){l(t,`Signer is not set, you must set it before executing an action`);let r={name:e.name,namespace:`main`,description:e.description,inputs:[this.#e(e.name,e.inputs)],types:this.#t(e.name)},i=(await this.client.execute(r,t,!1)).data?.tx_hash;if(!i)throw Error(`Kwil execute "${e.name}" did not return a transaction hash`);return n&&await this.waitForTx(i),i}async waitForTx(e){await re(e=>this.client.txInfo(e),e)}setSigner(e){this.signer=e}};const A=e=>async({nodeUrl:t,chainId:n})=>{let r=new e({kwilProvider:t,chainId:``});return n||=(await r.chainInfo({disableWarning:!0})).data?.chain_id,l(n,"Can't discover `chainId`. You must pass it explicitly."),new k(new e({kwilProvider:t,chainId:n,timeout:3e4}))},ie=A(s),ae=A(c);function j(e){return typeof e==`object`&&!!e&&`signatureType`in e&&e.signatureType===`mm_token`&&`identifier`in e&&`signer`in e&&typeof e.accessToken==`string`}function M(e){let t=e.mmTokenPayload?.storage_id;if(typeof t!=`string`||!t.trim())throw Error(`mm_token payload is missing storage_id`);return t.trim()}function N(e,t){return d(M(e),t)}function P(e){return typeof e==`object`&&!!e&&`payload`in e&&e.payload!==null&&typeof e.payload==`object`&&!Array.isArray(e.payload)&&`signature`in e&&typeof e.signature==`string`}function F(e,t){try{return JSON.parse(x(e))}catch(e){throw Error(t,{cause:e})}}function I(e,t){try{return p(e)}catch(e){throw Error(t,{cause:e})}}function L(e){let t,n;if(typeof e==`string`){let r=e.trim();if(!r)throw Error(`Invalid mm_token envelope: empty`);t=r;let i=F(I(r,`Invalid mm_token envelope encoding`),`Invalid mm_token envelope JSON`);if(!P(i))throw Error(`Invalid mm_token envelope: expected payload object and signature string`);n=i}else{if(!P(e))throw Error(`Invalid mm_token envelope: expected payload object and signature string`);n=e,t=m(S(JSON.stringify(n)))}let r=S(t),i=I(n.signature,`Invalid mm_token envelope signature encoding`);if(i.length!==64)throw Error(`Invalid mm_token signature length: expected 64, got ${i.length}`);let a=n.payload.signing_public_key;if(typeof a!=`string`)throw Error(`Invalid mm_token payload: missing signing_public_key`);let s=I(a,`Invalid mm_token signing_public_key encoding`);if(s.length!==32)throw Error(`Invalid mm_token signing_public_key length: expected 32, got ${s.length}`);let c=Object.assign(new o(async()=>r.slice(),s,`mm_token`),{mmTokenPayload:n.payload});return Object.defineProperty(c,"accessToken",{value:t,enumerable:!1})}function R({url:e,maxFetchBytes:t,mmAuth:n,...r}){let i=n??(j(r.signer)?r.signer:void 0);return new u({url:e,maxFetchBytes:t,accessToken:i?.accessToken,fetchFn:z(r)})}function z({kwilClient:e,signer:t,fetchFn:n=fetch,isAuthFailure:r=se}){let i=J(e),a,o=async()=>(a??=i.authenticateKGWAndSetCookie(t).finally(()=>{a=void 0}),a),s=async()=>{let e=i.getKgwCookie();return e?{cookie:e,refreshed:!1}:{cookie:await o(),refreshed:!0}};return async(e,t)=>{let{cookie:i}=await s(),a=await U(e,t),c=await n(...Y(e,W(a),i)),l=B(c);if(!await r(l.response))return c;await V(l.discardResponses);let u=await o();return n(...Y(e,W(a),u))}}function B(e){if(e.headers.get(`content-type`)?.includes(`application/json`)){let t=e.clone();return{response:t,discardResponses:[e,t]}}return{response:e,discardResponses:[e]}}async function V(e){await Promise.all(e.map(H))}async function H(e){if(!e.bodyUsed&&e.body)try{await e.body.cancel()}catch{}}async function U(e,t){if(t?.body!=null)return{requestInit:t,bufferedBody:await G(t.body)};if(e instanceof Request&&e.body!=null){let n=e.clone();return{requestInit:{...t,method:t?.method??e.method},bufferedBody:await G(n.body)}}return{requestInit:t}}function W({requestInit:e,bufferedBody:t}){return t?{...e,body:q(t)}:e}async function G(e){if(typeof e==`string`||e instanceof Blob||e instanceof ArrayBuffer||e instanceof URLSearchParams)return{kind:`body`,value:e};if(ArrayBuffer.isView(e))return{kind:`body`,value:new Uint8Array(e.buffer,e.byteOffset,e.byteLength)};if(e instanceof FormData){let t=[];return e.forEach((e,n)=>{t.push(K(n,e))}),{kind:`form-data`,entries:await Promise.all(t)}}return e instanceof ReadableStream?{kind:`body`,value:await new Response(e).arrayBuffer()}:{kind:`body`,value:e}}async function K(e,t){return typeof t==`string`?{key:e,value:t}:{key:e,value:await new Response(t).arrayBuffer(),fileName:t instanceof File?t.name:`blob`,type:t.type||`application/octet-stream`}}function q(e){if(e.kind===`body`)return e.value;let t=new FormData;for(let n of e.entries)`fileName`in n?t.append(n.key,new Blob([n.value],{type:n.type}),n.fileName):t.append(n.key,n.value);return t}function J(e){if(!(e.client instanceof s))throw Error(`KGW authenticated fetch can only be created from a NodeKwil client`);if(!oe(e.client))throw Error(`NodeKwil client does not expose KGW session cookie helpers`);return e.client}function oe(e){let t=e;return typeof t.getKgwCookie==`function`&&typeof t.authenticateKGWAndSetCookie==`function`}function Y(e,t,n){let r=new Headers(e instanceof Request?e.headers:void 0);return t?.headers&&new Headers(t.headers).forEach((e,t)=>{r.set(t,e)}),r.set(`Cookie`,n),[e,{...t,headers:r}]}async function se(e){if(e.status===401)return!0;if(!e.headers.get(`content-type`)?.includes(`application/json`))return!1;try{return(await e.json()).error?.code===-901}catch{return!1}}const ce={mainnet:{networkId:`mainnet`,nodeUrl:`https://rpc.mainnet.near.org`},testnet:{networkId:`testnet`,nodeUrl:`https://rpc.testnet.near.org`},betanet:{networkId:`betanet`,nodeUrl:`https://rpc.betanet.near.org`},shardnet:{networkId:`shardnet`,nodeUrl:`https://rpc.shardnet.near.org`}},le=e=>e.endsWith(`.near`)?`mainnet`:e.endsWith(`.testnet`)?`testnet`:e.endsWith(`.betanet`)?`betanet`:e.endsWith(`.shardnet`)?`shardnet`:`testnet`,ue=e=>{let t=le(e),n=ce[t];return{networkId:n.networkId,nodeUrl:n.nodeUrl}},de=[`browser`,`injected`,`instant-link`,`hardware`,`bridge`];function fe(e){return typeof e==`object`&&!!e&&`id`in e&&`metadata`in e&&`type`in e&&typeof e.type==`string`&&de.includes(e.type)}var X=class{bytes;constructor(e=32){this.bytes=crypto.getRandomValues(new Uint8Array(e))}get clampUTF8(){return this.bytes.map(e=>e&127)}};function Z(e,t){return async n=>{let r=typeof n==`string`?n:x(n);if(!e.signMessage)throw Error(`Only wallets with signMessage are supported.`);let i=Buffer.from(new X(32).bytes),{nonce:a=i,signature:o,callbackUrl:s}=await e.signMessage({message:r,recipient:t,nonce:i}),c={struct:{tag:`u32`,message:`string`,nonce:{array:{type:`u8`,len:32}},recipient:`string`,callbackUrl:{option:`string`}}},l={tag:2147484061,message:r,nonce:Array.from(a),recipient:t,callbackUrl:s},u=g(c,l);return v(h(u.length),u,f(o))}}function Q(e){let t=e.replace(/^ed25519:/,``);return b(ee(t),!0)}async function pe(e){let t;try{t=(await import(`near-api-js`)).connect}catch{throw Error(`Can't load near-api-js`)}let n=ue(e),r=await t(n);try{return(await r.connection.provider.query({request_type:`view_access_key_list`,finality:`final`,account_id:e})).keys.filter(e=>e.access_key.permission===`FullAccess`)?.map(e=>e.public_key)}catch{return}}async function me(e,t,n=`idos.network`){let r=await Z(e,n)(t);return b(r)}async function he(e,t,n,r,i=`idos.network`){if(!e.signMessage)throw Error(`Only wallets with signMessage are supported.`);if(e.id===`my-near-wallet`){let{accountId:r,signature:i,publicKey:a,error:o}=Object.fromEntries(new URLSearchParams(window.location.hash.slice(1)).entries());i&&(await n.set(`signer-address`,r),await n.set(`signer-public-key`,a));let s=e.signMessage.bind(e);e.signMessage=async({message:e,recipient:r})=>{if(o)return Promise.reject();let c=await n.get(`sign-last-message`),l=await n.get(`sign-last-nonce`);if(i&&e===c&&l){let r=Buffer.from(l),o=await n.get(`sign-last-url`);return Promise.resolve({accountId:t,publicKey:a,signature:i,nonce:r,message:e,callbackUrl:o})}let u=window.location.href,d=Buffer.from(new X(32).clampUTF8);return await n.set(`sign-last-message`,e),await n.set(`sign-last-nonce`,Array.from(d)),await n.set(`sign-last-url`,u),s({message:e,nonce:d,recipient:r,callbackUrl:u}),new Promise(()=>({}))}}let a=await n.get(`signer-address`),s=await n.get(`signer-public-key`);if(a!==t||!s){n.reset(),await r.client.auth.logoutKGW();let a=Buffer.from(new X(32).bytes),o=await e.signMessage({message:`idOS authentication`,recipient:i,nonce:a});if(!o)throw Error(`signMessage returned no result`);({publicKey:s}=o),await n.set(`signer-address`,t),await n.set(`signer-public-key`,s)}let c=Z(e,i);return{kwilSigner:new o(c,Q(s),`nep413`),publicKey:s}}function ge(e){return t=>async n=>{let r=x(n),i=crypto.getRandomValues(new Uint8Array(32)),a={struct:{message:`string`,nonce:{array:{type:`u8`,len:32}},recipient:`string`,callbackUrl:{option:`string`}}},o=2147484061,{signature:s}=t.sign(te(v(g(`u32`,o),g(a,{message:r,nonce:i,recipient:e})))),c={struct:{tag:`u32`,...a.struct}},l=g(c,{tag:o,message:r,nonce:i,recipient:e});return v(h(l.length),l,s)}}async function $(e,t,n,i,a){let s=await n.get(`signer-address`),c=await n.get(`signer-public-key`);if(s!==t||c&&c!==a)try{console.log(`logoutKGW`,i)}catch(e){console.error(`Failed to logout KGW:`,e)}return await n.set(`signer-address`,t),await n.set(`signer-public-key`,a),new o(async t=>{let n=await r(t,e);if(!n)throw Error(`Failed to sign transaction with XRP`);return Buffer.from(n,`hex`)},a,`xrpl`)}function _e(e){return typeof e==`object`&&!!e&&`publicKey`in e&&e.publicKey instanceof Uint8Array&&e.publicKey.length===C.sign.publicKeyLength&&`secretKey`in e&&e.secretKey instanceof Uint8Array&&e.secretKey.length===C.sign.secretKeyLength}function ve(e){return typeof e==`object`&&!!e&&`getPublicKey`in e&&`sign`in e&&typeof e.getPublicKey==`function`&&typeof e.sign==`function`}function ye(e){return typeof e==`object`&&!!e&&`publicKey`in e&&`sign`in e&&`canSign`in e&&typeof e.publicKey==`function`&&typeof e.sign==`function`&&typeof e.canSign==`function`}function be(e){return typeof e==`object`&&!!e&&`publicAddress`in e&&`signatureType`in e&&`publicKey`in e&&`signMessage`in e}function xe(e){return!!e&&typeof e==`object`&&`privateKey`in e&&`publicKey`in e}async function Se(e){if(j(e))return[e,m(e.identifier)];if(_e(e))return[new o(async t=>C.sign.detached(t,e.secretKey),e.publicKey,`ed25519`),Q(_(e.publicKey))];if(ve(e)){let t=e.getPublicKey().toString(),n=Q(t);return[new o(ge(`idos-issuer`)(e),n,`nep413`),t]}if(ye(e)){let t=e.publicKey(),n=e.rawPublicKey();return[new o(async t=>e.sign(Buffer.from(t)),n,`ed25519`),t]}if(xe(e)){let t;try{t=await import(`ripple-keypairs`)}catch(e){throw Error(`Can't load ripple-keypairs`,{cause:e})}return[new o(async n=>y(t.sign(b(n),e.privateKey)),e.publicKey,`xrpl`),e.publicKey]}return`address`in e?[new o(e,e.address),e.address]:(e=>{throw Error("Invalid `signer` type")})(e)}async function Ce(e,r,a){if(`connect`in a&&`address`in a){a=a;let t=await a.getAddress();if(await e.get(`signer-address`)!==t){e.set(`signer-address`,t);try{await r.client.auth.logoutKGW()}catch(e){console.log(`error logoutKGW`,e)}}return[new o(a,t),t,void 0,`EVM`]}if(fe(a)){let t=await a.getAccounts(),{kwilSigner:n,publicKey:i}=await he(a,t[0].accountId,e,r);return[n,t[0].accountId,i,`NEAR`]}if(i(a)){let{address:t,publicKey:i}=await n(a);if(!t)throw Error(`Failed to get XRP address`);return[await $(a,t,e,r,i),t,i,`XRPL`]}if(j(a)){let t=m(a.identifier);if(await e.get(`signer-address`)!==t){e.set(`signer-address`,t);try{await r.client.auth.logoutKGW()}catch(e){console.log(`error logoutKGW`,e)}}return[a,t,t,`MM`]}if(be(a)||a instanceof t){if(await e.get(`signer-address`)!==a.publicAddress){e.set(`signer-address`,a.publicAddress);try{await r.client.auth.logoutKGW()}catch(e){console.log(`error logoutKGW`,e)}}return[new o(async e=>a.signMessage(e),a.publicAddress,`ed25519`),a.publicAddress,a.publicKey,a.walletType]}return(e=>{throw Error("Invalid `signer` type")})(a)}export{k as KwilActionClient,a as KwilSigner,w as KwilTxFailedError,T as KwilTxPollTimeoutError,Ce as createClientKwilSigner,R as createKgwAuthenticatedBlobGateway,z as createKgwAuthenticatedFetch,L as createMmTokenAuth,ie as createNodeKwilClient,Se as createServerKwilSigner,ae as createWebKwilClient,pe as getNearFullAccessPublicKeys,Q as implicitAddressFromPublicKey,j as isMmTokenAuth,N as mmTokenCredentialContentUri,M as mmTokenStorageId,me as signNearMessage};
|
|
430
2
|
//# sourceMappingURL=index.mjs.map
|