@swapkit/wallet-keystore 1.8.23 → 4.0.0-beta.2
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/dist/index.cjs +4 -0
- package/dist/index.cjs.map +11 -0
- package/dist/index.js +3 -2
- package/dist/index.js.map +5 -5
- package/dist/types/helpers.d.ts +42 -0
- package/dist/types/helpers.d.ts.map +1 -0
- package/dist/types/index.d.ts +41 -0
- package/dist/types/index.d.ts.map +1 -0
- package/package.json +21 -25
- package/src/helpers.ts +0 -132
- package/src/index.ts +0 -2
- package/src/keystore.ts +0 -328
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
var D=Object.create;var{getPrototypeOf:E,defineProperty:m,getOwnPropertyNames:v,getOwnPropertyDescriptor:A}=Object,b=Object.prototype.hasOwnProperty;var y=(t,e,n)=>{n=t!=null?D(E(t)):{};let a=e||!t||!t.__esModule?m(n,"default",{value:t,enumerable:!0}):n;for(let o of v(t))if(!b.call(a,o))m(a,o,{get:()=>t[o],enumerable:!0});return a},w=new WeakMap,_=(t)=>{var e=w.get(t),n;if(e)return e;if(e=m({},"__esModule",{value:!0}),t&&typeof t==="object"||typeof t==="function")v(t).map((a)=>!b.call(e,a)&&m(e,a,{get:()=>t[a],enumerable:!(n=A(t,a))||n.enumerable}));return w.set(t,e),e};var R=(t,e)=>{for(var n in e)m(t,n,{get:e[n],enumerable:!0,configurable:!0,set:(a)=>e[n]=()=>a})};var j={};R(j,{validatePhrase:()=>F,keystoreWallet:()=>S,generatePhrase:()=>W,encryptToKeyStore:()=>U,decryptFromKeystore:()=>N,KEYSTORE_SUPPORTED_CHAINS:()=>Y});module.exports=_(j);var r=require("@swapkit/helpers"),d=require("@swapkit/wallet-core");var c=require("node:crypto"),u=require("@scure/bip39"),g=require("@scure/bip39/wordlists/english");async function k(t){let{blake2bFinal:e,blake2bInit:n,blake2bUpdate:a}=(await import("blakejs")).default,o=t;if(!(o instanceof Buffer))o=Buffer.from(o,"hex");let s=n(32);return a(s,o),Array.from(e(s)).map((i)=>i<16?`0${i.toString(16)}`:i.toString(16)).join("")}async function U(t,e){let a=c.randomBytes(16),o=c.randomBytes(32),s={c:262144,prf:"hmac-sha256",dklen:32,salt:o.toString("hex")},i=c.pbkdf2Sync(e,o,s.c,s.dklen,"sha256"),f=c.createCipheriv("aes-128-ctr",i.subarray(0,16),a),p=Buffer.concat([f.update(Buffer.from(t,"utf8")),f.final()]),l=Buffer.concat([i.subarray(16,32),Buffer.from(p)]),h=await k(l);return{meta:"xchain-keystore",version:1,crypto:{cipher:"aes-128-ctr",cipherparams:{iv:a.toString("hex")},ciphertext:p.toString("hex"),kdf:"pbkdf2",kdfparams:s,mac:h}}}function W(t=12){return u.generateMnemonic(g.wordlist,t===12?128:256)}function F(t){return u.validateMnemonic(t,g.wordlist)}async function N(t,e){let{SwapKitError:n}=await import("@swapkit/helpers");switch(t.version){case 1:{let a=t.crypto.kdfparams,o=Buffer.from(a.salt,"hex"),s=c.pbkdf2Sync(e,o,a.c,a.dklen,"sha256"),i=Buffer.from(t.crypto.ciphertext,"hex"),f=Buffer.concat([s.subarray(16,32),i]);if(await k(f)!==t.crypto.mac)throw new n("wallet_keystore_invalid_password");let l=c.createDecipheriv(t.crypto.cipher,s.subarray(0,16),Buffer.from(t.crypto.cipherparams.iv,"hex"));return Buffer.concat([l.update(i),l.final()]).toString("utf8")}default:throw new n("wallet_keystore_unsupported_version")}}var S=d.createWallet({name:"connectKeystore",walletType:r.WalletOption.KEYSTORE,supportedChains:[...r.EVMChains,...r.UTXOChains,...r.CosmosChains,r.Chain.Polkadot,r.Chain.Chainflip,r.Chain.Ripple,r.Chain.Solana,r.Chain.Tron,r.Chain.Near],connect:({addChain:t,supportedChains:e,walletType:n})=>async function a(o,s,i){let f=r.filterSupportedChains({chains:o,supportedChains:e,walletType:n});return await Promise.all(f.map(async(p)=>{let l=typeof i==="number"?i:0,h=i&&typeof i==="object"?i[p]:void 0,C=r.NetworkDerivationPath[p].slice(0,p===r.Chain.Solana?4:5),B=h||r.updateDerivationPath(C,{index:l}),{getToolbox:P}=await import("@swapkit/toolboxes"),x=await P(p,{phrase:s,derivationPath:B}),K=await x.getAddress()||"",T={...x,address:K};t({...T,chain:p,walletType:r.WalletOption.KEYSTORE})})),!0}}),Y=d.getWalletSupportedChains(S);
|
|
2
|
+
|
|
3
|
+
//# debugId=F337510ED6DB5EA264756E2164756E21
|
|
4
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/index.ts", "../src/helpers.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"import {\n Chain,\n CosmosChains,\n type DerivationPathArray,\n EVMChains,\n NetworkDerivationPath,\n UTXOChains,\n WalletOption,\n filterSupportedChains,\n updateDerivationPath,\n} from \"@swapkit/helpers\";\nimport { createWallet, getWalletSupportedChains } from \"@swapkit/wallet-core\";\n\nexport const keystoreWallet = createWallet({\n name: \"connectKeystore\",\n walletType: WalletOption.KEYSTORE,\n supportedChains: [\n ...EVMChains,\n ...UTXOChains,\n ...CosmosChains,\n Chain.Polkadot,\n Chain.Chainflip,\n Chain.Ripple,\n Chain.Solana,\n Chain.Tron,\n Chain.Near,\n ],\n connect: ({ addChain, supportedChains, walletType }) =>\n async function connectKeystore(\n chains: Chain[],\n phrase: string,\n derivationPathMapOrIndex?: { [chain in Chain]?: DerivationPathArray } | number,\n ) {\n const filteredChains = filterSupportedChains({ chains, supportedChains, walletType });\n\n await Promise.all(\n filteredChains.map(async (chain) => {\n const derivationPathIndex =\n typeof derivationPathMapOrIndex === \"number\" ? derivationPathMapOrIndex : 0;\n\n const derivationPathFromMap =\n derivationPathMapOrIndex && typeof derivationPathMapOrIndex === \"object\"\n ? derivationPathMapOrIndex[chain]\n : undefined;\n\n const derivationArrayToUpdate = NetworkDerivationPath[chain].slice(\n 0,\n chain === Chain.Solana ? 4 : 5,\n ) as DerivationPathArray;\n\n const derivationPath: DerivationPathArray =\n derivationPathFromMap ||\n updateDerivationPath(derivationArrayToUpdate, { index: derivationPathIndex });\n\n const { getToolbox } = await import(\"@swapkit/toolboxes\");\n\n const toolbox = await getToolbox(chain, { phrase, derivationPath });\n const address = (await toolbox.getAddress()) || \"\";\n\n const wallet = { ...toolbox, address };\n\n addChain({ ...wallet, chain, walletType: WalletOption.KEYSTORE });\n }),\n );\n\n return true;\n },\n});\n\nexport const KEYSTORE_SUPPORTED_CHAINS = getWalletSupportedChains(keystoreWallet);\n\nexport * from \"./helpers\";\n",
|
|
6
|
+
"import { createCipheriv, createDecipheriv, pbkdf2Sync, randomBytes } from \"node:crypto\";\nimport { generateMnemonic, validateMnemonic } from \"@scure/bip39\";\nimport { wordlist } from \"@scure/bip39/wordlists/english\";\n\nexport type Keystore = {\n version: number;\n meta: string;\n crypto: {\n cipher: string;\n cipherparams: { iv: string };\n ciphertext: string;\n kdf: string;\n kdfparams: { prf: string; dklen: number; salt: string; c: number };\n mac: string;\n };\n};\n\nasync function blake256(initData: Buffer | string) {\n const { blake2bFinal, blake2bInit, blake2bUpdate } = (await import(\"blakejs\")).default;\n let data = initData;\n\n if (!(data instanceof Buffer)) {\n // @ts-ignore\n data = Buffer.from(data, \"hex\");\n }\n\n const context = blake2bInit(32);\n blake2bUpdate(context, data);\n\n return Array.from(blake2bFinal(context))\n .map((byte) => (byte < 0x10 ? `0${byte.toString(16)}` : byte.toString(16)))\n .join(\"\");\n}\n\nexport async function encryptToKeyStore(phrase: string, password: string) {\n const cipher = \"aes-128-ctr\";\n const iv = randomBytes(16);\n const salt = randomBytes(32);\n const kdfParams = { c: 262144, prf: \"hmac-sha256\", dklen: 32, salt: salt.toString(\"hex\") };\n\n const derivedKey = pbkdf2Sync(password, salt, kdfParams.c, kdfParams.dklen, \"sha256\");\n const cipherIV = createCipheriv(cipher, derivedKey.subarray(0, 16), iv);\n const ciphertext = Buffer.concat([\n cipherIV.update(Buffer.from(phrase, \"utf8\")),\n cipherIV.final(),\n ]);\n const initData = Buffer.concat([derivedKey.subarray(16, 32), Buffer.from(ciphertext)]);\n const mac = await blake256(initData);\n\n return {\n meta: \"xchain-keystore\",\n version: 1,\n crypto: {\n cipher,\n cipherparams: { iv: iv.toString(\"hex\") },\n ciphertext: ciphertext.toString(\"hex\"),\n kdf: \"pbkdf2\",\n kdfparams: kdfParams,\n mac,\n },\n };\n}\n\nexport function generatePhrase(size: 12 | 24 = 12) {\n return generateMnemonic(wordlist, size === 12 ? 128 : 256);\n}\n\nexport function validatePhrase(phrase: string) {\n return validateMnemonic(phrase, wordlist);\n}\n\nexport async function decryptFromKeystore(keystore: Keystore, password: string) {\n const { SwapKitError } = await import(\"@swapkit/helpers\");\n\n switch (keystore.version) {\n case 1: {\n const kdfParams = keystore.crypto.kdfparams;\n const salt = Buffer.from(kdfParams.salt, \"hex\");\n const derivedKey = pbkdf2Sync(password, salt, kdfParams.c, kdfParams.dklen, \"sha256\");\n\n const ciphertext = Buffer.from(keystore.crypto.ciphertext, \"hex\");\n const initData = Buffer.concat([derivedKey.subarray(16, 32), ciphertext]);\n const mac = await blake256(initData);\n\n if (mac !== keystore.crypto.mac) {\n throw new SwapKitError(\"wallet_keystore_invalid_password\");\n }\n\n const decipher = createDecipheriv(\n keystore.crypto.cipher,\n derivedKey.subarray(0, 16),\n Buffer.from(keystore.crypto.cipherparams.iv, \"hex\"),\n );\n\n const phrase = Buffer.concat([decipher.update(ciphertext), decipher.final()]);\n return phrase.toString(\"utf8\");\n }\n\n default:\n throw new SwapKitError(\"wallet_keystore_unsupported_version\");\n }\n}\n"
|
|
7
|
+
],
|
|
8
|
+
"mappings": "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",
|
|
9
|
+
"debugId": "F337510ED6DB5EA264756E2164756E21",
|
|
10
|
+
"names": []
|
|
11
|
+
}
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
-
var
|
|
1
|
+
var P=Object.create;var{getPrototypeOf:K,defineProperty:d,getOwnPropertyNames:T}=Object;var D=Object.prototype.hasOwnProperty;var m=(t,o,a)=>{a=t!=null?P(K(t)):{};let n=o||!t||!t.__esModule?d(a,"default",{value:t,enumerable:!0}):a;for(let r of T(t))if(!D.call(n,r))d(n,r,{get:()=>t[r],enumerable:!0});return n};var h=((t)=>typeof require!=="undefined"?require:typeof Proxy!=="undefined"?new Proxy(t,{get:(o,a)=>(typeof require!=="undefined"?require:o)[a]}):t)(function(t){if(typeof require!=="undefined")return require.apply(this,arguments);throw Error('Dynamic require of "'+t+'" is not supported')});import{Chain as c,CosmosChains as U,EVMChains as W,NetworkDerivationPath as F,UTXOChains as N,WalletOption as v,filterSupportedChains as Y,updateDerivationPath as j}from"@swapkit/helpers";import{createWallet as O,getWalletSupportedChains as V}from"@swapkit/wallet-core";import{createCipheriv as E,createDecipheriv as A,pbkdf2Sync as g,randomBytes as y}from"node:crypto";import{generateMnemonic as _,validateMnemonic as R}from"@scure/bip39";import{wordlist as x}from"@scure/bip39/wordlists/english";async function w(t){let{blake2bFinal:o,blake2bInit:a,blake2bUpdate:n}=(await import("blakejs")).default,r=t;if(!(r instanceof Buffer))r=Buffer.from(r,"hex");let i=a(32);return n(i,r),Array.from(o(i)).map((e)=>e<16?`0${e.toString(16)}`:e.toString(16)).join("")}async function G(t,o){let n=y(16),r=y(32),i={c:262144,prf:"hmac-sha256",dklen:32,salt:r.toString("hex")},e=g(o,r,i.c,i.dklen,"sha256"),p=E("aes-128-ctr",e.subarray(0,16),n),s=Buffer.concat([p.update(Buffer.from(t,"utf8")),p.final()]),f=Buffer.concat([e.subarray(16,32),Buffer.from(s)]),l=await w(f);return{meta:"xchain-keystore",version:1,crypto:{cipher:"aes-128-ctr",cipherparams:{iv:n.toString("hex")},ciphertext:s.toString("hex"),kdf:"pbkdf2",kdfparams:i,mac:l}}}function I(t=12){return _(x,t===12?128:256)}function J(t){return R(t,x)}async function L(t,o){let{SwapKitError:a}=await import("@swapkit/helpers");switch(t.version){case 1:{let n=t.crypto.kdfparams,r=Buffer.from(n.salt,"hex"),i=g(o,r,n.c,n.dklen,"sha256"),e=Buffer.from(t.crypto.ciphertext,"hex"),p=Buffer.concat([i.subarray(16,32),e]);if(await w(p)!==t.crypto.mac)throw new a("wallet_keystore_invalid_password");let f=A(t.crypto.cipher,i.subarray(0,16),Buffer.from(t.crypto.cipherparams.iv,"hex"));return Buffer.concat([f.update(e),f.final()]).toString("utf8")}default:throw new a("wallet_keystore_unsupported_version")}}var H=O({name:"connectKeystore",walletType:v.KEYSTORE,supportedChains:[...W,...N,...U,c.Polkadot,c.Chainflip,c.Ripple,c.Solana,c.Tron,c.Near],connect:({addChain:t,supportedChains:o,walletType:a})=>async function n(r,i,e){let p=Y({chains:r,supportedChains:o,walletType:a});return await Promise.all(p.map(async(s)=>{let f=typeof e==="number"?e:0,l=e&&typeof e==="object"?e[s]:void 0,b=F[s].slice(0,s===c.Solana?4:5),k=l||j(b,{index:f}),{getToolbox:S}=await import("@swapkit/toolboxes"),u=await S(s,{phrase:i,derivationPath:k}),C=await u.getAddress()||"",B={...u,address:C};t({...B,chain:s,walletType:v.KEYSTORE})})),!0}}),tt=V(H);export{J as validatePhrase,H as keystoreWallet,I as generatePhrase,G as encryptToKeyStore,L as decryptFromKeystore,tt as KEYSTORE_SUPPORTED_CHAINS};
|
|
2
2
|
|
|
3
|
-
//# debugId=
|
|
3
|
+
//# debugId=ACC246C3A0D0567764756E2164756E21
|
|
4
|
+
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../src/
|
|
3
|
+
"sources": ["../src/index.ts", "../src/helpers.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"import {
|
|
6
|
-
"import {
|
|
5
|
+
"import {\n Chain,\n CosmosChains,\n type DerivationPathArray,\n EVMChains,\n NetworkDerivationPath,\n UTXOChains,\n WalletOption,\n filterSupportedChains,\n updateDerivationPath,\n} from \"@swapkit/helpers\";\nimport { createWallet, getWalletSupportedChains } from \"@swapkit/wallet-core\";\n\nexport const keystoreWallet = createWallet({\n name: \"connectKeystore\",\n walletType: WalletOption.KEYSTORE,\n supportedChains: [\n ...EVMChains,\n ...UTXOChains,\n ...CosmosChains,\n Chain.Polkadot,\n Chain.Chainflip,\n Chain.Ripple,\n Chain.Solana,\n Chain.Tron,\n Chain.Near,\n ],\n connect: ({ addChain, supportedChains, walletType }) =>\n async function connectKeystore(\n chains: Chain[],\n phrase: string,\n derivationPathMapOrIndex?: { [chain in Chain]?: DerivationPathArray } | number,\n ) {\n const filteredChains = filterSupportedChains({ chains, supportedChains, walletType });\n\n await Promise.all(\n filteredChains.map(async (chain) => {\n const derivationPathIndex =\n typeof derivationPathMapOrIndex === \"number\" ? derivationPathMapOrIndex : 0;\n\n const derivationPathFromMap =\n derivationPathMapOrIndex && typeof derivationPathMapOrIndex === \"object\"\n ? derivationPathMapOrIndex[chain]\n : undefined;\n\n const derivationArrayToUpdate = NetworkDerivationPath[chain].slice(\n 0,\n chain === Chain.Solana ? 4 : 5,\n ) as DerivationPathArray;\n\n const derivationPath: DerivationPathArray =\n derivationPathFromMap ||\n updateDerivationPath(derivationArrayToUpdate, { index: derivationPathIndex });\n\n const { getToolbox } = await import(\"@swapkit/toolboxes\");\n\n const toolbox = await getToolbox(chain, { phrase, derivationPath });\n const address = (await toolbox.getAddress()) || \"\";\n\n const wallet = { ...toolbox, address };\n\n addChain({ ...wallet, chain, walletType: WalletOption.KEYSTORE });\n }),\n );\n\n return true;\n },\n});\n\nexport const KEYSTORE_SUPPORTED_CHAINS = getWalletSupportedChains(keystoreWallet);\n\nexport * from \"./helpers\";\n",
|
|
6
|
+
"import { createCipheriv, createDecipheriv, pbkdf2Sync, randomBytes } from \"node:crypto\";\nimport { generateMnemonic, validateMnemonic } from \"@scure/bip39\";\nimport { wordlist } from \"@scure/bip39/wordlists/english\";\n\nexport type Keystore = {\n version: number;\n meta: string;\n crypto: {\n cipher: string;\n cipherparams: { iv: string };\n ciphertext: string;\n kdf: string;\n kdfparams: { prf: string; dklen: number; salt: string; c: number };\n mac: string;\n };\n};\n\nasync function blake256(initData: Buffer | string) {\n const { blake2bFinal, blake2bInit, blake2bUpdate } = (await import(\"blakejs\")).default;\n let data = initData;\n\n if (!(data instanceof Buffer)) {\n // @ts-ignore\n data = Buffer.from(data, \"hex\");\n }\n\n const context = blake2bInit(32);\n blake2bUpdate(context, data);\n\n return Array.from(blake2bFinal(context))\n .map((byte) => (byte < 0x10 ? `0${byte.toString(16)}` : byte.toString(16)))\n .join(\"\");\n}\n\nexport async function encryptToKeyStore(phrase: string, password: string) {\n const cipher = \"aes-128-ctr\";\n const iv = randomBytes(16);\n const salt = randomBytes(32);\n const kdfParams = { c: 262144, prf: \"hmac-sha256\", dklen: 32, salt: salt.toString(\"hex\") };\n\n const derivedKey = pbkdf2Sync(password, salt, kdfParams.c, kdfParams.dklen, \"sha256\");\n const cipherIV = createCipheriv(cipher, derivedKey.subarray(0, 16), iv);\n const ciphertext = Buffer.concat([\n cipherIV.update(Buffer.from(phrase, \"utf8\")),\n cipherIV.final(),\n ]);\n const initData = Buffer.concat([derivedKey.subarray(16, 32), Buffer.from(ciphertext)]);\n const mac = await blake256(initData);\n\n return {\n meta: \"xchain-keystore\",\n version: 1,\n crypto: {\n cipher,\n cipherparams: { iv: iv.toString(\"hex\") },\n ciphertext: ciphertext.toString(\"hex\"),\n kdf: \"pbkdf2\",\n kdfparams: kdfParams,\n mac,\n },\n };\n}\n\nexport function generatePhrase(size: 12 | 24 = 12) {\n return generateMnemonic(wordlist, size === 12 ? 128 : 256);\n}\n\nexport function validatePhrase(phrase: string) {\n return validateMnemonic(phrase, wordlist);\n}\n\nexport async function decryptFromKeystore(keystore: Keystore, password: string) {\n const { SwapKitError } = await import(\"@swapkit/helpers\");\n\n switch (keystore.version) {\n case 1: {\n const kdfParams = keystore.crypto.kdfparams;\n const salt = Buffer.from(kdfParams.salt, \"hex\");\n const derivedKey = pbkdf2Sync(password, salt, kdfParams.c, kdfParams.dklen, \"sha256\");\n\n const ciphertext = Buffer.from(keystore.crypto.ciphertext, \"hex\");\n const initData = Buffer.concat([derivedKey.subarray(16, 32), ciphertext]);\n const mac = await blake256(initData);\n\n if (mac !== keystore.crypto.mac) {\n throw new SwapKitError(\"wallet_keystore_invalid_password\");\n }\n\n const decipher = createDecipheriv(\n keystore.crypto.cipher,\n derivedKey.subarray(0, 16),\n Buffer.from(keystore.crypto.cipherparams.iv, \"hex\"),\n );\n\n const phrase = Buffer.concat([decipher.update(ciphertext), decipher.final()]);\n return phrase.toString(\"utf8\");\n }\n\n default:\n throw new SwapKitError(\"wallet_keystore_unsupported_version\");\n }\n}\n"
|
|
7
7
|
],
|
|
8
|
-
"mappings": "0lBAAA,yBAAS,sBAAgB,
|
|
9
|
-
"debugId": "
|
|
8
|
+
"mappings": "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",
|
|
9
|
+
"debugId": "ACC246C3A0D0567764756E2164756E21",
|
|
10
10
|
"names": []
|
|
11
11
|
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
export type Keystore = {
|
|
2
|
+
version: number;
|
|
3
|
+
meta: string;
|
|
4
|
+
crypto: {
|
|
5
|
+
cipher: string;
|
|
6
|
+
cipherparams: {
|
|
7
|
+
iv: string;
|
|
8
|
+
};
|
|
9
|
+
ciphertext: string;
|
|
10
|
+
kdf: string;
|
|
11
|
+
kdfparams: {
|
|
12
|
+
prf: string;
|
|
13
|
+
dklen: number;
|
|
14
|
+
salt: string;
|
|
15
|
+
c: number;
|
|
16
|
+
};
|
|
17
|
+
mac: string;
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
export declare function encryptToKeyStore(phrase: string, password: string): Promise<{
|
|
21
|
+
meta: string;
|
|
22
|
+
version: number;
|
|
23
|
+
crypto: {
|
|
24
|
+
cipher: string;
|
|
25
|
+
cipherparams: {
|
|
26
|
+
iv: string;
|
|
27
|
+
};
|
|
28
|
+
ciphertext: string;
|
|
29
|
+
kdf: string;
|
|
30
|
+
kdfparams: {
|
|
31
|
+
c: number;
|
|
32
|
+
prf: string;
|
|
33
|
+
dklen: number;
|
|
34
|
+
salt: string;
|
|
35
|
+
};
|
|
36
|
+
mac: string;
|
|
37
|
+
};
|
|
38
|
+
}>;
|
|
39
|
+
export declare function generatePhrase(size?: 12 | 24): string;
|
|
40
|
+
export declare function validatePhrase(phrase: string): boolean;
|
|
41
|
+
export declare function decryptFromKeystore(keystore: Keystore, password: string): Promise<string>;
|
|
42
|
+
//# sourceMappingURL=helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/helpers.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,QAAQ,GAAG;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE;QACN,MAAM,EAAE,MAAM,CAAC;QACf,YAAY,EAAE;YAAE,EAAE,EAAE,MAAM,CAAA;SAAE,CAAC;QAC7B,UAAU,EAAE,MAAM,CAAC;QACnB,GAAG,EAAE,MAAM,CAAC;QACZ,SAAS,EAAE;YAAE,GAAG,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAC;YAAC,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;QACnE,GAAG,EAAE,MAAM,CAAC;KACb,CAAC;CACH,CAAC;AAmBF,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;;;;;;;;;;;;;;;;;;GA2BvE;AAED,wBAAgB,cAAc,CAAC,IAAI,GAAE,EAAE,GAAG,EAAO,UAEhD;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,WAE5C;AAED,wBAAsB,mBAAmB,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,mBA8B7E"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { Chain, type DerivationPathArray } from "@swapkit/helpers";
|
|
2
|
+
export declare const keystoreWallet: {
|
|
3
|
+
connectKeystore: {
|
|
4
|
+
connectWallet: (connectParams: {
|
|
5
|
+
addChain: import("@swapkit/helpers").AddChainType;
|
|
6
|
+
}) => (chains: Chain[], phrase: string, derivationPathMapOrIndex?: number | {
|
|
7
|
+
ARB?: DerivationPathArray | undefined;
|
|
8
|
+
AURORA?: DerivationPathArray | undefined;
|
|
9
|
+
AVAX?: DerivationPathArray | undefined;
|
|
10
|
+
BASE?: DerivationPathArray | undefined;
|
|
11
|
+
BERA?: DerivationPathArray | undefined;
|
|
12
|
+
BSC?: DerivationPathArray | undefined;
|
|
13
|
+
BTC?: DerivationPathArray | undefined;
|
|
14
|
+
BCH?: DerivationPathArray | undefined;
|
|
15
|
+
GAIA?: DerivationPathArray | undefined;
|
|
16
|
+
DASH?: DerivationPathArray | undefined;
|
|
17
|
+
DOGE?: DerivationPathArray | undefined;
|
|
18
|
+
ETH?: DerivationPathArray | undefined;
|
|
19
|
+
FIAT?: DerivationPathArray | undefined;
|
|
20
|
+
GNO?: DerivationPathArray | undefined;
|
|
21
|
+
KUJI?: DerivationPathArray | undefined;
|
|
22
|
+
LTC?: DerivationPathArray | undefined;
|
|
23
|
+
MAYA?: DerivationPathArray | undefined;
|
|
24
|
+
NEAR?: DerivationPathArray | undefined;
|
|
25
|
+
OP?: DerivationPathArray | undefined;
|
|
26
|
+
DOT?: DerivationPathArray | undefined;
|
|
27
|
+
FLIP?: DerivationPathArray | undefined;
|
|
28
|
+
POL?: DerivationPathArray | undefined;
|
|
29
|
+
XRD?: DerivationPathArray | undefined;
|
|
30
|
+
XRP?: DerivationPathArray | undefined;
|
|
31
|
+
THOR?: DerivationPathArray | undefined;
|
|
32
|
+
SOL?: DerivationPathArray | undefined;
|
|
33
|
+
TRX?: DerivationPathArray | undefined;
|
|
34
|
+
ZEC?: DerivationPathArray | undefined;
|
|
35
|
+
} | undefined) => Promise<boolean>;
|
|
36
|
+
supportedChains: (Chain.Arbitrum | Chain.Aurora | Chain.Avalanche | Chain.Base | Chain.Berachain | Chain.BinanceSmartChain | Chain.Bitcoin | Chain.BitcoinCash | Chain.Cosmos | Chain.Dash | Chain.Dogecoin | Chain.Ethereum | Chain.Gnosis | Chain.Kujira | Chain.Litecoin | Chain.Maya | Chain.Near | Chain.Optimism | Chain.Polkadot | Chain.Chainflip | Chain.Polygon | Chain.Ripple | Chain.THORChain | Chain.Solana | Chain.Tron | Chain.Zcash)[];
|
|
37
|
+
};
|
|
38
|
+
};
|
|
39
|
+
export declare const KEYSTORE_SUPPORTED_CHAINS: (Chain.Arbitrum | Chain.Aurora | Chain.Avalanche | Chain.Base | Chain.Berachain | Chain.BinanceSmartChain | Chain.Bitcoin | Chain.BitcoinCash | Chain.Cosmos | Chain.Dash | Chain.Dogecoin | Chain.Ethereum | Chain.Gnosis | Chain.Kujira | Chain.Litecoin | Chain.Maya | Chain.Near | Chain.Optimism | Chain.Polkadot | Chain.Chainflip | Chain.Polygon | Chain.Ripple | Chain.THORChain | Chain.Solana | Chain.Tron | Chain.Zcash)[];
|
|
40
|
+
export * from "./helpers";
|
|
41
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,EAEL,KAAK,mBAAmB,EAOzB,MAAM,kBAAkB,CAAC;AAG1B,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsDzB,CAAC;AAEH,eAAO,MAAM,yBAAyB,waAA2C,CAAC;AAElF,cAAc,WAAW,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,40 +1,36 @@
|
|
|
1
1
|
{
|
|
2
|
+
"author": "swapkit-oss",
|
|
2
3
|
"dependencies": {
|
|
3
|
-
"@
|
|
4
|
-
"@swapkit/
|
|
5
|
-
"@swapkit/
|
|
6
|
-
"@swapkit/toolbox-evm": "1.11.7",
|
|
7
|
-
"@swapkit/toolbox-radix": "1.3.16",
|
|
8
|
-
"@swapkit/toolbox-ripple": "1.0.22",
|
|
9
|
-
"@swapkit/toolbox-solana": "1.6.17",
|
|
10
|
-
"@swapkit/toolbox-substrate": "1.4.16",
|
|
11
|
-
"@swapkit/toolbox-tron": "0.0.5",
|
|
12
|
-
"@swapkit/toolbox-utxo": "1.4.17",
|
|
13
|
-
"blakejs": "1.2.1",
|
|
14
|
-
"micro-key-producer": "0.7.5"
|
|
4
|
+
"@swapkit/helpers": "4.0.0-beta.34",
|
|
5
|
+
"@swapkit/toolboxes": "4.0.0-beta.51",
|
|
6
|
+
"@swapkit/wallet-core": "4.0.0-beta.2"
|
|
15
7
|
},
|
|
16
|
-
"description": "SwapKit Wallet
|
|
17
|
-
"
|
|
18
|
-
"
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
8
|
+
"description": "SwapKit - Wallet Keystore",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"import": "./dist/index.js",
|
|
12
|
+
"require": "./dist/index.cjs",
|
|
13
|
+
"types": "./dist/types/index.d.ts"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"files": ["dist/"],
|
|
17
|
+
"homepage": "https://github.com/swapkit/SwapKit",
|
|
22
18
|
"license": "Apache-2.0",
|
|
23
|
-
"main": "./dist/index.js",
|
|
24
19
|
"name": "@swapkit/wallet-keystore",
|
|
25
20
|
"repository": {
|
|
21
|
+
"directory": "packages/wallet-keystore",
|
|
26
22
|
"type": "git",
|
|
27
|
-
"url": "git+https://github.com/
|
|
23
|
+
"url": "git+https://github.com/swapkit/SwapKit.git"
|
|
28
24
|
},
|
|
29
25
|
"scripts": {
|
|
30
26
|
"build": "bun run ./build.ts",
|
|
27
|
+
"build:clean": "rm -rf dist && bun run ./build.ts",
|
|
31
28
|
"clean": "rm -rf dist node_modules *.tsbuildinfo",
|
|
32
|
-
"lint": "biome check --diagnostic-level=error --write ./src",
|
|
33
29
|
"test": "echo 'bun test'",
|
|
34
|
-
"test:
|
|
35
|
-
"type-check": "tsc --noEmit"
|
|
30
|
+
"test:ci": "echo 'bun test --coverage'",
|
|
31
|
+
"type-check": "bun tsc --noEmit",
|
|
32
|
+
"type-check:go": "tsgo"
|
|
36
33
|
},
|
|
37
34
|
"type": "module",
|
|
38
|
-
"
|
|
39
|
-
"version": "1.8.23"
|
|
35
|
+
"version": "4.0.0-beta.2"
|
|
40
36
|
}
|
package/src/helpers.ts
DELETED
|
@@ -1,132 +0,0 @@
|
|
|
1
|
-
import { createCipheriv, createDecipheriv, pbkdf2, randomBytes } from "node:crypto";
|
|
2
|
-
import { generateMnemonic, validateMnemonic } from "@scure/bip39";
|
|
3
|
-
import { wordlist } from "@scure/bip39/wordlists/english";
|
|
4
|
-
import blakejs from "blakejs";
|
|
5
|
-
|
|
6
|
-
export type Keystore = {
|
|
7
|
-
crypto: {
|
|
8
|
-
cipher: string;
|
|
9
|
-
ciphertext: string;
|
|
10
|
-
cipherparams: {
|
|
11
|
-
iv: string;
|
|
12
|
-
};
|
|
13
|
-
kdf: string;
|
|
14
|
-
kdfparams: {
|
|
15
|
-
prf: string;
|
|
16
|
-
dklen: number;
|
|
17
|
-
salt: string;
|
|
18
|
-
c: number;
|
|
19
|
-
};
|
|
20
|
-
mac: string;
|
|
21
|
-
};
|
|
22
|
-
version: number;
|
|
23
|
-
meta: string;
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* taken from `foundry-primitives` and modified
|
|
28
|
-
*/
|
|
29
|
-
const blake256 = (initData: Buffer | string): string => {
|
|
30
|
-
let data = initData;
|
|
31
|
-
|
|
32
|
-
if (!(data instanceof Buffer)) {
|
|
33
|
-
// @ts-ignore
|
|
34
|
-
data = Buffer.from(data, "hex");
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
const context = blakejs.blake2bInit(32);
|
|
38
|
-
blakejs.blake2bUpdate(context, data);
|
|
39
|
-
|
|
40
|
-
return Array.from(blakejs.blake2bFinal(context))
|
|
41
|
-
.map((byte) => (byte < 0x10 ? `0${byte.toString(16)}` : byte.toString(16)))
|
|
42
|
-
.join("");
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
const pbkdf2Async = (
|
|
46
|
-
passphrase: string | Buffer,
|
|
47
|
-
salt: string | Buffer,
|
|
48
|
-
iterations: number,
|
|
49
|
-
keylen: number,
|
|
50
|
-
digest: string,
|
|
51
|
-
) =>
|
|
52
|
-
new Promise<Buffer>((resolve, reject) => {
|
|
53
|
-
pbkdf2(passphrase, salt, iterations, keylen, digest, (error, drived) => {
|
|
54
|
-
if (error) {
|
|
55
|
-
reject(error);
|
|
56
|
-
} else {
|
|
57
|
-
resolve(drived);
|
|
58
|
-
}
|
|
59
|
-
});
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
export const encryptToKeyStore = async (phrase: string, password: string) => {
|
|
63
|
-
const salt = randomBytes(32);
|
|
64
|
-
const iv = randomBytes(16);
|
|
65
|
-
const kdfParams = { c: 262144, prf: "hmac-sha256", dklen: 32, salt: salt.toString("hex") };
|
|
66
|
-
const cipher = "aes-128-ctr";
|
|
67
|
-
|
|
68
|
-
const derivedKey = await pbkdf2Async(
|
|
69
|
-
Buffer.from(password),
|
|
70
|
-
salt,
|
|
71
|
-
kdfParams.c,
|
|
72
|
-
kdfParams.dklen,
|
|
73
|
-
"sha256",
|
|
74
|
-
);
|
|
75
|
-
const cipherIV = createCipheriv(cipher, derivedKey.subarray(0, 16), iv);
|
|
76
|
-
const ciphertext = Buffer.concat([
|
|
77
|
-
cipherIV.update(Buffer.from(phrase, "utf8")),
|
|
78
|
-
cipherIV.final(),
|
|
79
|
-
]);
|
|
80
|
-
|
|
81
|
-
return {
|
|
82
|
-
meta: "xchain-keystore",
|
|
83
|
-
version: 1,
|
|
84
|
-
crypto: {
|
|
85
|
-
cipher,
|
|
86
|
-
cipherparams: { iv: iv.toString("hex") },
|
|
87
|
-
ciphertext: ciphertext.toString("hex"),
|
|
88
|
-
kdf: "pbkdf2",
|
|
89
|
-
kdfparams: kdfParams,
|
|
90
|
-
mac: blake256(Buffer.concat([derivedKey.subarray(16, 32), Buffer.from(ciphertext)])),
|
|
91
|
-
},
|
|
92
|
-
};
|
|
93
|
-
};
|
|
94
|
-
|
|
95
|
-
export const generatePhrase = (size: 12 | 24 = 12) => {
|
|
96
|
-
return generateMnemonic(wordlist, size === 12 ? 128 : 256);
|
|
97
|
-
};
|
|
98
|
-
|
|
99
|
-
export const validatePhrase = (phrase: string) => {
|
|
100
|
-
return validateMnemonic(phrase, wordlist);
|
|
101
|
-
};
|
|
102
|
-
|
|
103
|
-
export const decryptFromKeystore = async (keystore: Keystore, password: string) => {
|
|
104
|
-
switch (keystore.version) {
|
|
105
|
-
case 1: {
|
|
106
|
-
const kdfparams = keystore.crypto.kdfparams;
|
|
107
|
-
const derivedKey = await pbkdf2Async(
|
|
108
|
-
Buffer.from(password),
|
|
109
|
-
Buffer.from(kdfparams.salt, "hex"),
|
|
110
|
-
kdfparams.c,
|
|
111
|
-
kdfparams.dklen,
|
|
112
|
-
"sha256",
|
|
113
|
-
);
|
|
114
|
-
|
|
115
|
-
const ciphertext = Buffer.from(keystore.crypto.ciphertext, "hex");
|
|
116
|
-
const mac = blake256(Buffer.concat([derivedKey.subarray(16, 32), ciphertext]));
|
|
117
|
-
|
|
118
|
-
if (mac !== keystore.crypto.mac) throw new Error("Invalid password");
|
|
119
|
-
const decipher = createDecipheriv(
|
|
120
|
-
keystore.crypto.cipher,
|
|
121
|
-
derivedKey.subarray(0, 16),
|
|
122
|
-
Buffer.from(keystore.crypto.cipherparams.iv, "hex"),
|
|
123
|
-
);
|
|
124
|
-
|
|
125
|
-
const phrase = Buffer.concat([decipher.update(ciphertext), decipher.final()]);
|
|
126
|
-
return phrase.toString("utf8");
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
default:
|
|
130
|
-
throw new Error("Unsupported keystore version");
|
|
131
|
-
}
|
|
132
|
-
};
|
package/src/index.ts
DELETED
package/src/keystore.ts
DELETED
|
@@ -1,328 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
Chain,
|
|
3
|
-
type ChainApis,
|
|
4
|
-
type ConnectWalletParams,
|
|
5
|
-
CosmosChains,
|
|
6
|
-
type DerivationPathArray,
|
|
7
|
-
EVMChains,
|
|
8
|
-
NetworkDerivationPath,
|
|
9
|
-
UTXOChains,
|
|
10
|
-
WalletOption,
|
|
11
|
-
type Witness,
|
|
12
|
-
derivationPathToString,
|
|
13
|
-
filterSupportedChains,
|
|
14
|
-
getRPCUrl,
|
|
15
|
-
pickEvmApiKey,
|
|
16
|
-
setRequestClientConfig,
|
|
17
|
-
updatedLastIndex,
|
|
18
|
-
} from "@swapkit/helpers";
|
|
19
|
-
import type { DepositParam, TransferParams } from "@swapkit/toolbox-cosmos";
|
|
20
|
-
import type {
|
|
21
|
-
Psbt,
|
|
22
|
-
TransactionType,
|
|
23
|
-
UTXOTransferParams,
|
|
24
|
-
UTXOWalletTransferParams,
|
|
25
|
-
} from "@swapkit/toolbox-utxo";
|
|
26
|
-
|
|
27
|
-
const KEYSTORE_SUPPORTED_CHAINS = [
|
|
28
|
-
...EVMChains,
|
|
29
|
-
...UTXOChains,
|
|
30
|
-
...CosmosChains,
|
|
31
|
-
Chain.Polkadot,
|
|
32
|
-
Chain.Chainflip,
|
|
33
|
-
Chain.Solana,
|
|
34
|
-
Chain.Ripple,
|
|
35
|
-
Chain.Tron,
|
|
36
|
-
] as const;
|
|
37
|
-
|
|
38
|
-
type KeystoreOptions = {
|
|
39
|
-
ethplorerApiKey?: string;
|
|
40
|
-
blockchairApiKey?: string;
|
|
41
|
-
covalentApiKey?: string;
|
|
42
|
-
swapkitApiKey?: string;
|
|
43
|
-
stagenet?: boolean;
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
type Params = KeystoreOptions & {
|
|
47
|
-
apis?: ChainApis;
|
|
48
|
-
rpcUrl?: string;
|
|
49
|
-
chain: Chain;
|
|
50
|
-
phrase: string;
|
|
51
|
-
derivationPath: string;
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
const getWalletMethodsForChain = async ({
|
|
55
|
-
apis,
|
|
56
|
-
rpcUrl,
|
|
57
|
-
chain,
|
|
58
|
-
phrase,
|
|
59
|
-
ethplorerApiKey,
|
|
60
|
-
covalentApiKey,
|
|
61
|
-
blockchairApiKey,
|
|
62
|
-
swapkitApiKey,
|
|
63
|
-
derivationPath,
|
|
64
|
-
stagenet,
|
|
65
|
-
}: Params) => {
|
|
66
|
-
switch (chain) {
|
|
67
|
-
case Chain.Arbitrum:
|
|
68
|
-
case Chain.Avalanche:
|
|
69
|
-
case Chain.Base:
|
|
70
|
-
case Chain.BinanceSmartChain:
|
|
71
|
-
case Chain.Ethereum:
|
|
72
|
-
case Chain.Optimism:
|
|
73
|
-
case Chain.Polygon: {
|
|
74
|
-
const { getProvider, getToolboxByChain } = await import("@swapkit/toolbox-evm");
|
|
75
|
-
const { HDNodeWallet } = await import("ethers");
|
|
76
|
-
|
|
77
|
-
const api = apis?.[chain];
|
|
78
|
-
|
|
79
|
-
const apiKey = pickEvmApiKey({
|
|
80
|
-
chain,
|
|
81
|
-
nonEthApiKey: covalentApiKey,
|
|
82
|
-
ethApiKey: ethplorerApiKey,
|
|
83
|
-
});
|
|
84
|
-
const provider = getProvider(chain, rpcUrl);
|
|
85
|
-
const wallet = HDNodeWallet.fromPhrase(phrase).connect(provider);
|
|
86
|
-
const params = { api, apiKey, provider, signer: wallet };
|
|
87
|
-
|
|
88
|
-
return { address: wallet.address, walletMethods: getToolboxByChain(chain)(params) };
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
case Chain.BitcoinCash: {
|
|
92
|
-
const { BCHToolbox } = await import("@swapkit/toolbox-utxo");
|
|
93
|
-
|
|
94
|
-
const api = apis?.[chain];
|
|
95
|
-
|
|
96
|
-
const toolbox = BCHToolbox({ rpcUrl, apiKey: blockchairApiKey, apiClient: api });
|
|
97
|
-
const keys = await toolbox.createKeysForPath({ phrase, derivationPath });
|
|
98
|
-
const address = toolbox.getAddressFromKeys(keys);
|
|
99
|
-
|
|
100
|
-
function signTransaction({ builder, utxos }: Awaited<ReturnType<typeof toolbox.buildBCHTx>>) {
|
|
101
|
-
utxos.forEach((utxo, index) => {
|
|
102
|
-
builder.sign(index, keys, undefined, 0x41, (utxo.witnessUtxo as Witness).value);
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
return builder.build();
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
const walletMethods = {
|
|
109
|
-
...toolbox,
|
|
110
|
-
transfer: (
|
|
111
|
-
params: UTXOWalletTransferParams<
|
|
112
|
-
Awaited<ReturnType<typeof toolbox.buildBCHTx>>,
|
|
113
|
-
TransactionType
|
|
114
|
-
>,
|
|
115
|
-
) => toolbox.transfer({ ...params, from: address, signTransaction }),
|
|
116
|
-
};
|
|
117
|
-
|
|
118
|
-
return { address, walletMethods };
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
case Chain.Bitcoin:
|
|
122
|
-
case Chain.Dash:
|
|
123
|
-
case Chain.Dogecoin:
|
|
124
|
-
case Chain.Litecoin: {
|
|
125
|
-
const { getToolboxByChain } = await import("@swapkit/toolbox-utxo");
|
|
126
|
-
|
|
127
|
-
const api = apis?.[chain];
|
|
128
|
-
|
|
129
|
-
const toolbox = getToolboxByChain(chain)({
|
|
130
|
-
rpcUrl,
|
|
131
|
-
apiKey: blockchairApiKey,
|
|
132
|
-
apiClient: api,
|
|
133
|
-
});
|
|
134
|
-
|
|
135
|
-
const keys = toolbox.createKeysForPath({ phrase, derivationPath });
|
|
136
|
-
const address = toolbox.getAddressFromKeys(keys);
|
|
137
|
-
|
|
138
|
-
return {
|
|
139
|
-
address,
|
|
140
|
-
walletMethods: {
|
|
141
|
-
...toolbox,
|
|
142
|
-
transfer: (params: UTXOTransferParams) =>
|
|
143
|
-
toolbox.transfer({
|
|
144
|
-
...params,
|
|
145
|
-
from: address,
|
|
146
|
-
signTransaction: (psbt: Psbt) => psbt.signAllInputs(keys),
|
|
147
|
-
}),
|
|
148
|
-
},
|
|
149
|
-
};
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
case Chain.Cosmos:
|
|
153
|
-
case Chain.Kujira: {
|
|
154
|
-
const { getToolboxByChain } = await import("@swapkit/toolbox-cosmos");
|
|
155
|
-
|
|
156
|
-
const api = apis?.[chain];
|
|
157
|
-
|
|
158
|
-
const toolbox = getToolboxByChain(chain)({ server: api, stagenet, swapkitApiKey });
|
|
159
|
-
const address = await toolbox.getAddressFromMnemonic(phrase);
|
|
160
|
-
const signer = await toolbox.getSigner(phrase);
|
|
161
|
-
|
|
162
|
-
const transfer = (params: TransferParams) => toolbox.transfer({ ...params, signer });
|
|
163
|
-
|
|
164
|
-
return { address, walletMethods: { ...toolbox, transfer } };
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
case Chain.Maya:
|
|
168
|
-
case Chain.THORChain: {
|
|
169
|
-
const { getToolboxByChain } = await import("@swapkit/toolbox-cosmos");
|
|
170
|
-
|
|
171
|
-
const api = apis?.[chain];
|
|
172
|
-
|
|
173
|
-
const toolbox = getToolboxByChain(chain)({ server: api, stagenet });
|
|
174
|
-
const signer = await toolbox.getSigner(phrase);
|
|
175
|
-
const address = await toolbox.getAddressFromMnemonic(phrase);
|
|
176
|
-
|
|
177
|
-
return {
|
|
178
|
-
address,
|
|
179
|
-
walletMethods: {
|
|
180
|
-
...toolbox,
|
|
181
|
-
deposit: ({ assetValue, memo }: DepositParam) =>
|
|
182
|
-
toolbox.deposit({ assetValue, memo, from: address, signer }),
|
|
183
|
-
transfer: (params: TransferParams) =>
|
|
184
|
-
toolbox.transfer({ ...params, from: address, signer }),
|
|
185
|
-
signMessage: async (message: string) => {
|
|
186
|
-
const privateKey = await toolbox.createPrivateKeyFromPhrase(phrase);
|
|
187
|
-
return toolbox.signWithPrivateKey({ privateKey, message });
|
|
188
|
-
},
|
|
189
|
-
},
|
|
190
|
-
};
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
case Chain.Polkadot:
|
|
194
|
-
case Chain.Chainflip: {
|
|
195
|
-
const { Network, getToolboxByChain, createKeyring } = await import(
|
|
196
|
-
"@swapkit/toolbox-substrate"
|
|
197
|
-
);
|
|
198
|
-
|
|
199
|
-
const signer = await createKeyring(phrase, Network[chain].prefix);
|
|
200
|
-
const toolbox = await getToolboxByChain(chain, {
|
|
201
|
-
signer,
|
|
202
|
-
providerUrl:
|
|
203
|
-
chain === Chain.Polkadot ? getRPCUrl(Chain.Polkadot) : getRPCUrl(Chain.Chainflip),
|
|
204
|
-
});
|
|
205
|
-
|
|
206
|
-
return { address: signer.address, walletMethods: toolbox };
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
case Chain.Solana: {
|
|
210
|
-
const { SOLToolbox, createKeysForPath } = await import("@swapkit/toolbox-solana");
|
|
211
|
-
const signer = createKeysForPath({ phrase, derivationPath });
|
|
212
|
-
const toolbox = SOLToolbox({ rpcUrl, signer });
|
|
213
|
-
|
|
214
|
-
return {
|
|
215
|
-
address: toolbox.getAddressFromKeys(signer),
|
|
216
|
-
walletMethods: {
|
|
217
|
-
...toolbox,
|
|
218
|
-
},
|
|
219
|
-
};
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
case Chain.Ripple: {
|
|
223
|
-
const { XRPToolbox, createSigner } = await import("@swapkit/toolbox-ripple");
|
|
224
|
-
const signer = createSigner(phrase);
|
|
225
|
-
const toolbox = await XRPToolbox({ rpcUrl, signer });
|
|
226
|
-
|
|
227
|
-
return {
|
|
228
|
-
address: signer.address,
|
|
229
|
-
walletMethods: {
|
|
230
|
-
...toolbox,
|
|
231
|
-
},
|
|
232
|
-
};
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
case Chain.Tron: {
|
|
236
|
-
const { createTronToolbox } = await import("@swapkit/toolbox-tron");
|
|
237
|
-
const toolbox = await createTronToolbox({ rpcUrl, phrase, derivationPath });
|
|
238
|
-
|
|
239
|
-
return {
|
|
240
|
-
address: await toolbox.getAddress(),
|
|
241
|
-
walletMethods: {
|
|
242
|
-
...toolbox,
|
|
243
|
-
},
|
|
244
|
-
};
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
default:
|
|
248
|
-
throw new Error(`Unsupported chain ${chain}`);
|
|
249
|
-
}
|
|
250
|
-
};
|
|
251
|
-
|
|
252
|
-
function connectKeystore({
|
|
253
|
-
addChain,
|
|
254
|
-
apis,
|
|
255
|
-
rpcUrls,
|
|
256
|
-
config: {
|
|
257
|
-
thorswapApiKey,
|
|
258
|
-
covalentApiKey,
|
|
259
|
-
ethplorerApiKey,
|
|
260
|
-
blockchairApiKey,
|
|
261
|
-
stagenet,
|
|
262
|
-
swapkitApiKey,
|
|
263
|
-
},
|
|
264
|
-
}: ConnectWalletParams) {
|
|
265
|
-
return async function connectKeystore(
|
|
266
|
-
chains: Chain[],
|
|
267
|
-
phrase: string,
|
|
268
|
-
derivationPathMapOrIndex?: { [chain in Chain]?: DerivationPathArray } | number,
|
|
269
|
-
) {
|
|
270
|
-
setRequestClientConfig({ apiKey: thorswapApiKey });
|
|
271
|
-
|
|
272
|
-
const supportedChains = filterSupportedChains(
|
|
273
|
-
chains,
|
|
274
|
-
KEYSTORE_SUPPORTED_CHAINS,
|
|
275
|
-
WalletOption.KEYSTORE,
|
|
276
|
-
);
|
|
277
|
-
|
|
278
|
-
const promises = supportedChains.map(async (chain) => {
|
|
279
|
-
const derivationPathIndex =
|
|
280
|
-
typeof derivationPathMapOrIndex === "number" ? derivationPathMapOrIndex : 0;
|
|
281
|
-
|
|
282
|
-
const derivationPathFromMap =
|
|
283
|
-
derivationPathMapOrIndex && typeof derivationPathMapOrIndex === "object"
|
|
284
|
-
? derivationPathMapOrIndex[chain]
|
|
285
|
-
: undefined;
|
|
286
|
-
|
|
287
|
-
const [first, second, third, fourth, fifth] = NetworkDerivationPath[chain];
|
|
288
|
-
|
|
289
|
-
const derivationPathArray: DerivationPathArray =
|
|
290
|
-
derivationPathFromMap ||
|
|
291
|
-
updatedLastIndex(
|
|
292
|
-
chain === Chain.Solana
|
|
293
|
-
? [first, second, third, fourth]
|
|
294
|
-
: [first, second, third, fourth, fifth],
|
|
295
|
-
derivationPathIndex,
|
|
296
|
-
);
|
|
297
|
-
|
|
298
|
-
const derivationPath = derivationPathToString(derivationPathArray);
|
|
299
|
-
|
|
300
|
-
const { address, walletMethods } = await getWalletMethodsForChain({
|
|
301
|
-
derivationPath,
|
|
302
|
-
chain,
|
|
303
|
-
apis,
|
|
304
|
-
rpcUrl: rpcUrls[chain],
|
|
305
|
-
covalentApiKey,
|
|
306
|
-
ethplorerApiKey,
|
|
307
|
-
phrase,
|
|
308
|
-
blockchairApiKey,
|
|
309
|
-
swapkitApiKey,
|
|
310
|
-
stagenet,
|
|
311
|
-
});
|
|
312
|
-
|
|
313
|
-
addChain({
|
|
314
|
-
...walletMethods,
|
|
315
|
-
chain,
|
|
316
|
-
address,
|
|
317
|
-
balance: [],
|
|
318
|
-
walletType: WalletOption.KEYSTORE,
|
|
319
|
-
});
|
|
320
|
-
});
|
|
321
|
-
|
|
322
|
-
await Promise.all(promises);
|
|
323
|
-
|
|
324
|
-
return true;
|
|
325
|
-
};
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
export const keystoreWallet = { connectKeystore } as const;
|