Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Add MayaChain (CACAO) #662

Open
wants to merge 40 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
f4e7af0
Native work
BitHighlander Jan 12, 2024
786ac76
KeepKey working
BitHighlander Jan 24, 2024
9fd87cc
KeepKey integration tests
BitHighlander Jan 24, 2024
82cfb68
sigs
BitHighlander Jan 24, 2024
28e7665
uncomment
BitHighlander Jan 24, 2024
49e9a9c
new txs and sigs
BitHighlander Jan 30, 2024
d3b80d7
Merge branch 'master' of https://github.com/shapeshift/hdwallet into …
BitHighlander Jan 30, 2024
f638ce7
clean up tests
BitHighlander Jan 30, 2024
908084b
Merge pull request #12 from keepkey/feature-maya-final
BitHighlander Jan 30, 2024
4974a65
feat(common): remove unused wallet adapters
pastaghost Jan 30, 2024
91bdd35
feat(sandbox): remove references to old packages
pastaghost Jan 30, 2024
d015f12
cleanup(integration): remove unused package references
pastaghost Jan 30, 2024
7d20d39
cleanup(hdwallet-native): remove unused package references
pastaghost Jan 30, 2024
fba5998
cleanup(hdwallet-core): remove unused package references
pastaghost Jan 30, 2024
3258e5c
cleanup(hdwallet-sandbox): remove unused portis app id
pastaghost Jan 30, 2024
d349149
cleanup(common): remove unused package references
pastaghost Jan 30, 2024
c885341
cleanup(common): remove unused package references
pastaghost Jan 30, 2024
8c0d7e7
chore(sandbox): update package namespaces
pastaghost Feb 12, 2024
73b2a38
chore(integration): update package namespaces
pastaghost Feb 12, 2024
7a36ec0
chore(core): update package namespaces
pastaghost Feb 12, 2024
7825c81
chore(keepkey): update package namespaces
pastaghost Feb 12, 2024
1a23d54
chore(native): update package namespaces
pastaghost Feb 12, 2024
95cb933
fix(common): update README
pastaghost Feb 12, 2024
10e06cf
chore(common): update package namespaces
pastaghost Feb 12, 2024
18f74aa
chore(keepkey): update package namespaces
pastaghost Feb 12, 2024
c880547
chore(native): update package namespaces
pastaghost Feb 12, 2024
62d0a6d
chore(integration): update package namespaces
pastaghost Feb 12, 2024
534cc59
chore(sandbox): update package namespaces
pastaghost Feb 12, 2024
55ad56a
chore(common): update package namespaces
pastaghost Feb 12, 2024
2503792
chore(keepkey): update package versions
pastaghost Feb 12, 2024
7b49d45
chore(native): update package versions
pastaghost Feb 12, 2024
f463019
chore(core): update package versions
pastaghost Feb 12, 2024
9ce9b99
chore(sandbox): update package versions, upgrade parcel
pastaghost Feb 12, 2024
8341b01
chore(integration): update package versions, update package namespaces
pastaghost Feb 12, 2024
f9eafb6
chore(common): upgrade lerna
pastaghost Feb 12, 2024
34e895a
chore(common): update package namespaces
pastaghost Feb 12, 2024
b44bd96
chore(common): upgrade node
pastaghost Feb 12, 2024
587d90f
Merge pull request #13 from keepkey/remove-unused-packages
BitHighlander Feb 12, 2024
f5f46c0
Revert "fix(common): remove unused packages"
BitHighlander Feb 12, 2024
b817657
Merge pull request #14 from keepkey/revert-13-remove-unused-packages
BitHighlander Feb 12, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion examples/sandbox/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,13 @@ <h4>Arkeo</h4>
<button class="button button-outline" id="arkeoAddClaim">Add Claim</button>
<input type="text" id="arkeoResults" />
</div>

<div class="container">
<h4>MAYAChain</h4>
<h5>Native MAYA</h5>
<button class="button button-outline" id="mayachainAddr">Address</button>
<button class="button button-outline" id="mayachainTx">Tx</button>
<input type="text" id="mayachainNativeResults" />
</div>
<div class="container">
<h4>THORChain</h4>
<h5>Native RUNE</h5>
Expand Down
54 changes: 53 additions & 1 deletion examples/sandbox/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ import * as dogeTxJson from "./json/dogeTx.json";
import { eip712, txs } from "./json/ethereum/ethTx.json";
import { openSeaListNFTMessage } from "./json/ethereum/OpenSea-ethSignTypedDataV4.json";
import * as ltcTxJson from "./json/ltcTx.json";
import { mayachainUnsignedTx } from "./json/mayachainTx.json";
import {
osmosisDelegateTx,
osmosisIBCTransferTx,
Expand All @@ -72,7 +73,6 @@ import {
thorchainRouterAbi,
thorchainUnsignedTx,
} from "./json/thorchainTx.json";

const keyring = new core.Keyring();

const portisAppId = "ff763d3d-9e34-45a1-81d1-caa39b9c64f9";
Expand Down Expand Up @@ -1269,7 +1269,59 @@ $cosmosIBCTransfer.on("click", async (e) => {
$cosmosResults.val(label + " does not support Cosmos");
}
});
/*
* MAYAChain
*/
const $mayachainAddr = $("#mayachainAddr");
const $mayachainTx = $("#mayachainTx");
const $mayachainNativeResults = $("#mayachainNativeResults");

$mayachainAddr.on("click", async (e) => {
e.preventDefault();
if (!wallet) {
$mayachainNativeResults.val("No wallet?");
return;
}
// eslint-disable-next-line no-console
console.log(core);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

?

if (true) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

?

const { addressNList } = wallet.mayachainGetAccountPaths({ accountIdx: 0 })[0];
const result = await wallet.mayachainGetAddress({
addressNList,
showDisplay: false,
});
await wallet.mayachainGetAddress({
addressNList,
showDisplay: true,
});
$mayachainNativeResults.val(result);
} else {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pretty sure this is never going to it as the else block of if (true)

const label = await wallet.getLabel();
$mayachainNativeResults.val(label + " does not support THORChain");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

?

}
});
$mayachainTx.on("click", async (e) => {
e.preventDefault();
if (!wallet) {
$mayachainNativeResults.val("No wallet?");
return;
}
if (true) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also what?

// eslint-disable-next-line no-console
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we sure about disabling this rule here?

console.log("mayachainUnsignedTx: ", mayachainUnsignedTx);
const res = await wallet.mayachainSignTx({
addressNList: core.bip32ToAddressNList(`m/44'/931'/0'/0/0`),
gomesalexandre marked this conversation as resolved.
Show resolved Hide resolved
chain_id: "mayachain-mainnet-v1",
account_number: "6359",
sequence: "15",
tx: mayachainUnsignedTx,
});
$mayachainNativeResults.val(JSON.stringify(res));
} else {
const label = await wallet.getLabel();
$mayachainNativeResults.val(label + " does not support MAYAchain");
}
});
/*
* THORChain
*/
Expand Down
30 changes: 30 additions & 0 deletions examples/sandbox/json/mayachainTx.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"mayachainUnsignedTx": {
"fee": {
"amount": [
{
"amount": "1",
"denom": "cacao"
}
],
"gas": "200000"
},
"memo": "foobar",
"msg": [
{
"type": "mayachain/MsgSend",
"value": {
"amount": [
{
"amount": "1",
"denom": "cacao"
}
],
"from_address": "maya1ls33ayg26kmltw7jjy55p32ghjna09zp7z4etj",
"to_address": "maya1ls33ayg26kmltw7jjy55p32ghjna09zp7z4etj"
}
}
],
"signatures": null
}
}
9 changes: 9 additions & 0 deletions integration/src/integration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { eosTests } from "./eos";
import { ethTests } from "./ethereum";
import { fioTests } from "./fio";
import { kavaTests } from "./kava";
import { mayachainTests } from "./mayachain";
import { osmosisTests } from "./osmosis";
import { rippleTests } from "./ripple";
import { secretTests } from "./secret";
Expand Down Expand Up @@ -136,6 +137,14 @@ export function integration(suite: WalletSuite): void {
thorchainTests(() => ({ wallet, info }));
});

describe("mayachainTests", () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't follow the naming convention of tests in this file. Shouldn't this be MayaChainWallet ?

beforeAll(async () => {
wallet = await suite.createWallet("Thorchain");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this correct?

});

mayachainTests(() => ({ wallet, info }));
});

describe("SecretWallet", () => {
beforeAll(async () => {
wallet = await suite.createWallet("Secret");
Expand Down
7 changes: 7 additions & 0 deletions integration/src/mayachain/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import * as core from "@shapeshiftoss/hdwallet-core";

import { mayachainTests as tests } from "./mayachain";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you follow the naming convention of the integrations module, you won't have to alias the import


export function mayachainTests(get: () => { wallet: core.HDWallet; info: core.HDWalletInfo }): void {
tests(get);
}
144 changes: 144 additions & 0 deletions integration/src/mayachain/mayachain.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
import * as core from "@shapeshiftoss/hdwallet-core";
import * as keepkey from "@shapeshiftoss/hdwallet-keepkey";
import * as ledger from "@shapeshiftoss/hdwallet-ledger";

import tx_unsigned_swap_amino from "./tx01.mainnet.mayachain.swap.amino.json";
import tx_unsigned_swap from "./tx01.mainnet.mayachain.swap.json";
import tx_signed_swap_amino from "./tx01.mainnet.mayachain.swap.signed.amino.json";
import tx_signed_swap from "./tx01.mainnet.mayachain.swap.signed.json";
import tx_unsigned_transfer_amino from "./tx01.mainnet.mayachain.transfer.amino.json";
import tx_unsigned_transfer from "./tx01.mainnet.mayachain.transfer.json";
import tx_signed_transfer_amino from "./tx01.mainnet.mayachain.transfer.signed.amino.json";
import tx_signed_transfer from "./tx01.mainnet.mayachain.transfer.signed.json";

const MNEMONIC12_NOPIN_NOPASSPHRASE = "alcohol woman abuse must during monitor noble actual mixed trade anger aisle";

const TIMEOUT = 60 * 1000;

/**
* Main integration suite for testing MayachainWallet implementations' Mayachain support.
*/
export function mayachainTests(get: () => { wallet: core.HDWallet; info: core.HDWalletInfo }): void {
let wallet: core.MayachainWallet & core.HDWallet;
let useAmino: boolean;

describe("Mayachain", () => {
beforeAll(async () => {
const { wallet: w } = get();
if (core.supportsMayachain(w)) wallet = w;
useAmino = w instanceof keepkey.KeepKeyHDWallet || w instanceof ledger.LedgerHDWallet;
});

beforeEach(async () => {
if (!wallet) return;
await wallet.wipe();
await wallet.loadDevice({
mnemonic: MNEMONIC12_NOPIN_NOPASSPHRASE,
label: "test",
skipChecksum: true,
});
}, TIMEOUT);

test(
"mayachainGetAccountPaths()",
() => {
if (!wallet) return;
const paths = wallet.mayachainGetAccountPaths({ accountIdx: 0 });
expect(paths.length > 0).toBe(true);
expect(paths[0].addressNList[0] > 0x80000000).toBe(true);
},
TIMEOUT
);

test(
"describePath() mayachain",
async () => {
if (!wallet) return;

const out = wallet.describePath({
path: core.bip32ToAddressNList("m/44'/931'/0'/0/0"),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto path question here

coin: "Mayachain",
});

// This is strange, and probably wrong, behavior... but it's what happens.
if (wallet.getVendor() === "KeepKey") {
// eslint-disable-next-line jest/no-conditional-expect
expect(out).toMatchInlineSnapshot(`
Object {
"coin": "Mayachain",
"isKnown": false,
"scriptType": undefined,
"verbose": "m/44'/931'/0'/0/0",
}
`);
} else {
// eslint-disable-next-line jest/no-conditional-expect
expect(out).toMatchInlineSnapshot(`
Object {
"accountIdx": 0,
"coin": "Mayachain",
"isKnown": true,
"isPrefork": false,
"verbose": "Mayachain Account #0",
"wholeAccount": true,
}
`);
}
},
TIMEOUT
);

test(
"mayachainGetAddress()",
async () => {
if (!wallet) return;
expect(
await wallet.mayachainGetAddress({
addressNList: core.bip32ToAddressNList("m/44'/931'/0'/0/0"),
showDisplay: false,
testnet: false,
})
).toEqual("maya1ls33ayg26kmltw7jjy55p32ghjna09zp7z4etj");
},
TIMEOUT
);

describe("mayachainSignTx()", () => {
it.each([
[
"should correctly sign a transfer tx",
tx_unsigned_transfer_amino,
tx_unsigned_transfer,
tx_signed_transfer_amino,
tx_signed_transfer,
],
[
"should correctly sign a swap tx",
tx_unsigned_swap_amino,
tx_unsigned_swap,
tx_signed_swap_amino,
tx_signed_swap,
],
])(
"%s",
async (_, aminoTx, protoTx, signedAminoTx, signedProtoTx) => {
const tx = useAmino ? aminoTx : protoTx;
const signedTx = useAmino ? signedAminoTx : signedProtoTx;

if (!wallet || !tx) return;

const input: core.MayachainSignTx = {
tx,
addressNList: core.bip32ToAddressNList("m/44'/931'/0'/0/0"),
chain_id: tx.chain_id,
account_number: tx.account_number,
sequence: tx.sequence,
};
const res = await wallet.mayachainSignTx(input);
expect(res).toEqual(signedTx);
},
TIMEOUT
);
});
});
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"account_number": "6359",
"chain_id": "mayachain-mainnet-v1",
"sequence": "20",
"fee": {
"amount": [
{
"amount": "0",
"denom": "cacao"
}
],
"gas": "350000"
},
"memo": "",
"msg": [
{
"type": "mayachain/MsgDeposit",
"value": {
"coins": [
{
"asset": "MAYA.CACAO",
"amount": "1000000"
}
],
"memo": "SWAP:DASH.DASH:XdTw4G5AWW4cogGd7ayybyBNDbuB45UpgH:10000",
"signer": "maya1ls33ayg26kmltw7jjy55p32ghjna09zp7z4etj"
}
}
],
"signatures": []
}
31 changes: 31 additions & 0 deletions integration/src/mayachain/tx01.mainnet.mayachain.swap.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"account_number": "6359",
"chain_id": "mayachain-mainnet-v1",
"sequence": "20",
"fee": {
"amount": [
{
"amount": "0",
"denom": "cacao"
}
],
"gas": "350000"
},
"memo": "",
"msg": [
{
"type": "mayachain/MsgDeposit",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

using amino type for proto tx

"value": {
"coins": [
{
"asset": "MAYA.CACAO",
"amount": "1000000"
}
],
"memo": "SWAP:DASH.DASH:XdTw4G5AWW4cogGd7ayybyBNDbuB45UpgH:10000",
"signer": "maya1ls33ayg26kmltw7jjy55p32ghjna09zp7z4etj"
}
}
],
"signatures": []
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"serialized": "CogBCoUBChEvdHlwZXMuTXNnRGVwb3NpdBJwCh8KFAoETUFZQRIFQ0FDQU8aBUNBQ0FPEgcxMDAwMDAwEjdTV0FQOkRBU0guREFTSDpYZFR3NEc1QVdXNGNvZ0dkN2F5eWJ5Qk5EYnVCNDVVcGdIOjEwMDAwGhT8Ix6RCtW39bvSkSlAxUi8p9eUQRJkClAKRgofL2Nvc21vcy5jcnlwdG8uc2VjcDI1NmsxLlB1YktleRIjCiEDFRlxO4tCvcNnES0zEyzxTO35KKxXcdREukWblJcRe6MSBAoCCAEYFBIQCgoKBWNhY2FvEgEwELCuFRpAORL7NmFPsTZE8i/35JVAf5dMXQG/Pr+RDkGZ+PTyTk5lAjsJkO+kPfLoI5NZ8/yhvznS3A7oiNGLhaftcSNmpw==",
"body": "CpABChEvdHlwZXMuTXNnRGVwb3NpdBJ7CiAKFAoETUFZQRIFQ0FDQU8aBUNBQ0FPEgg1MDk5NDAwMBJBU1dBUDpFVEguRVRIOjB4M2YyMzI5QzlBREZiY0NkOUE4NGY1MmM5MDZFOTM2QTQyZEExOENCODozNDg5NTM1MDEaFPwjHpEK1bf1u9KRKUDFSLyn15RB",
"authInfoBytes": "ClAKRgofL2Nvc21vcy5jcnlwdG8uc2VjcDI1NmsxLlB1YktleRIjCiEDFRlxO4tCvcNnES0zEyzxTO35KKxXcdREukWblJcRe6MSBAoCCAEYFBIQCgoKBWNhY2FvEgEwELCuFQ==",
"signatures": [
"ORL7NmFPsTZE8i/35JVAf5dMXQG/Pr+RDkGZ+PTyTk5lAjsJkO+kPfLoI5NZ8/yhvznS3A7oiNGLhaftcSNmpw=="
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"serialized": "CogBCoUBChEvdHlwZXMuTXNnRGVwb3NpdBJwCh8KFAoETUFZQRIFQ0FDQU8aBUNBQ0FPEgcxMDAwMDAwEjdTV0FQOkRBU0guREFTSDpYZFR3NEc1QVdXNGNvZ0dkN2F5eWJ5Qk5EYnVCNDVVcGdIOjEwMDAwGhT8Ix6RCtW39bvSkSlAxUi8p9eUQRJkClAKRgofL2Nvc21vcy5jcnlwdG8uc2VjcDI1NmsxLlB1YktleRIjCiEDFRlxO4tCvcNnES0zEyzxTO35KKxXcdREukWblJcRe6MSBAoCCAEYFBIQCgoKBWNhY2FvEgEwELCuFRpAORL7NmFPsTZE8i/35JVAf5dMXQG/Pr+RDkGZ+PTyTk5lAjsJkO+kPfLoI5NZ8/yhvznS3A7oiNGLhaftcSNmpw==",
"body": "CoUBChEvdHlwZXMuTXNnRGVwb3NpdBJwCh8KFAoETUFZQRIFQ0FDQU8aBUNBQ0FPEgcxMDAwMDAwEjdTV0FQOkRBU0guREFTSDpYZFR3NEc1QVdXNGNvZ0dkN2F5eWJ5Qk5EYnVCNDVVcGdIOjEwMDAwGhT8Ix6RCtW39bvSkSlAxUi8p9eUQQ==",
"authInfoBytes": "ClAKRgofL2Nvc21vcy5jcnlwdG8uc2VjcDI1NmsxLlB1YktleRIjCiEDFRlxO4tCvcNnES0zEyzxTO35KKxXcdREukWblJcRe6MSBAoCCAEYFBIQCgoKBWNhY2FvEgEwELCuFQ==",
"signatures": [
"ORL7NmFPsTZE8i/35JVAf5dMXQG/Pr+RDkGZ+PTyTk5lAjsJkO+kPfLoI5NZ8/yhvznS3A7oiNGLhaftcSNmpw=="
]
}
Loading