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

feat!: change coin type to IOTA #4

Merged
merged 3 commits into from
Jun 12, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
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
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -149,19 +149,19 @@ Then, one can use `generic-cli` like this:

- Get a public key for a BIP-32 derivation without prompting the user:
```shell-session
$ generic-cli getAddress --use-block "44'/784'/0'/0'/0'"
$ generic-cli getAddress --use-block "44'/4218'/0'/0'/0'"
a42e71c004770d1a48956090248a8d7d86ee02726b5aab2a5cd15ca9f57cbd71
```

- Show the address on device for a BIP-32 derivation and obtain the public key:
```shell-session
$ generic-cli getAddress --use-block --verify "44'/535348'/0'/0/0"
$ generic-cli getAddress --use-block --verify "44'/4218'/0'/0/0"
a42e71c004770d1a48956090248a8d7d86ee02726b5aab2a5cd15ca9f57cbd71
```

- Sign a transaction:
```shell-session
$ generic-cli sign --use-block "44'/784'/0'/0'/0'" '00000000050205546e7f126d2f40331a543b9608439b582fd0d103000000000000002080fdabcc90498e7eb8413b140c4334871eeafa5a86203fd9cfdb032f604f49e1284af431cf032b5d85324135bf9a3073e920d7f5020000000000000020a06f410c175e828c24cee84cb3bd95cff25c33fbbdcb62c6596e8e423784ffe701d08074075c7097f361e8b443e2075a852a2292e80180969800000000001643fb2578ff7191c643079a62c1cca8ec2752bc05546e7f126d2f40331a543b9608439b582fd0d103000000000000002080fdabcc90498e7eb8413b140c4334871eeafa5a86203fd9cfdb032f604f49e101000000000000002c01000000000000'
$ generic-cli sign --use-block "44'/4218'/0'/0'/0'" '00000000050205546e7f126d2f40331a543b9608439b582fd0d103000000000000002080fdabcc90498e7eb8413b140c4334871eeafa5a86203fd9cfdb032f604f49e1284af431cf032b5d85324135bf9a3073e920d7f5020000000000000020a06f410c175e828c24cee84cb3bd95cff25c33fbbdcb62c6596e8e423784ffe701d08074075c7097f361e8b443e2075a852a2292e80180969800000000001643fb2578ff7191c643079a62c1cca8ec2752bc05546e7f126d2f40331a543b9608439b582fd0d103000000000000002080fdabcc90498e7eb8413b140c4334871eeafa5a86203fd9cfdb032f604f49e101000000000000002c01000000000000'
Signing: <Buffer 1f 41 2f 22 53 11 f5 89 eb 3e a8 fd 05 d3 de 9e 1f 41 2f 22 53 11 f5 89 eb 3e a8 fd 05 d3 de 9e 1f 41 2f 22 53 11 f5 89 eb 3e a8 fd 05 d3 de 9e f8 f2 ... 14 more bytes>
906a1d402aa17b32e96903b1a42ba0df9b690157e6b9a974a36b81ee023a7e6bd39eeaa40cab270e6451dff4d820044c982bfd12a6fa88c0f5b758c0d8b67201
```
Expand Down
2 changes: 1 addition & 1 deletion guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ Install the Sui app on your Ledger device to manage SUI Tokens with the [Sui Wal

- Open the Sui wallet and select "Connect to Ledger device".

- Enter the derivation path (default `m/44'/784'/0'/0/0`).
- Enter the derivation path (default `m/44'/4218'/0'/0/0`).

- You can use this account to receive Sui tokens.

Expand Down
2 changes: 1 addition & 1 deletion rust-app/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ overflow-checks = false

[package.metadata.ledger]
name = "Sui"
path = ["44'/784'"]
path = ["44'/4218'"]
curve = ["ed25519"]
flags = "0"

Expand Down
2 changes: 1 addition & 1 deletion rust-app/src/implementation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ pub const BIP_PATH_PARSER: BipParserImplT = SubInterp(DefaultInterp);

// Need a path of length 5, as make_bip32_path panics with smaller paths
pub const BIP32_PREFIX: [u32; 5] =
ledger_device_sdk::ecc::make_bip32_path(b"m/44'/784'/123'/0'/0'");
ledger_device_sdk::ecc::make_bip32_path(b"m/44'/4218'/123'/0'/0'");

pub async fn get_address_apdu(io: HostIO, prompt: bool) {
let input = match io.get_params::<1>() {
Expand Down
12 changes: 6 additions & 6 deletions ts-tests/public-key-tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@ import type Sui from "./Sui";

describe('public key tests', () => {

afterEach( async function() {
await Axios.post(BASE_URL + "/automation", {version: 1, rules: []});
afterEach(async function () {
await Axios.post(BASE_URL + "/automation", { version: 1, rules: [] });
await Axios.delete(BASE_URL + "/events");
});

it('provides a public key', async () => {

await sendCommandAndAccept(async (client : Sui) => {
const rv = await client.getPublicKey("44'/784'/0'");
await sendCommandAndAccept(async (client: Sui) => {
const rv = await client.getPublicKey("44'/4218'/0'");
expect(new Buffer(rv.publicKey).toString('hex')).to.equal("6fc6f39448ad7af0953b78b16d0f840e6fe718ba4a89384239ff20ed088da2fa");
expect(new Buffer(rv.address).toString('hex')).to.equal("56b19e720f3bfa8caaef806afdd5dfaffd0d6ec9476323a14d1638ad734b2ba5");
return;
Expand All @@ -23,8 +23,8 @@ describe('public key tests', () => {

it('does address verification', async () => {

await sendCommandAndAccept(async (client : Sui) => {
const rv = await client.verifyAddress("44'/784'/0'");
await sendCommandAndAccept(async (client: Sui) => {
const rv = await client.verifyAddress("44'/4218'/0'");
expect(new Buffer(rv.publicKey).toString('hex')).to.equal("6fc6f39448ad7af0953b78b16d0f840e6fe718ba4a89384239ff20ed088da2fa");
expect(new Buffer(rv.address).toString('hex')).to.equal("56b19e720f3bfa8caaef806afdd5dfaffd0d6ec9476323a14d1638ad734b2ba5");
return;
Expand Down
152 changes: 76 additions & 76 deletions ts-tests/signing-tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ import type Sui from "./Sui";
import * as blake2b from "blake2b";
import { instantiate, Nacl } from "js-nacl";

let nacl : Nacl =null;
let nacl: Nacl = null;

instantiate(n => { nacl=n; });
instantiate(n => { nacl = n; });

function testTransaction(path: string, txn: Buffer, prompts: any[]) {
return async () => {
await sendCommandAndAccept(async (client : Sui) => {
await sendCommandAndAccept(async (client: Sui) => {

const { publicKey } = await client.getPublicKey(path);

Expand All @@ -22,84 +22,84 @@ function testTransaction(path: string, txn: Buffer, prompts: any[]) {
const sig = await client.signTransaction(path, txn);
expect(sig.signature.length).to.equal(64);
const pass = nacl.crypto_sign_verify_detached(
sig.signature,
blake2b(32).update(txn).digest(),
publicKey,
sig.signature,
blake2b(32).update(txn).digest(),
publicKey,
);
expect(pass).to.equal(true);
}, prompts);
}
}

describe("Signing tests", function() {
before( async function() {
while(!nacl) await new Promise(r => setTimeout(r, 100));
describe("Signing tests", function () {
before(async function () {
while (!nacl) await new Promise(r => setTimeout(r, 100));
})

it("can sign a transaction",
testTransaction(
"44'/784'/0'",
Buffer.from("000000000002000840420f000000000000204f2370b2a4810ad6c8e1cfd92cc8c8818fef8f59e3a80cea17871f78d850ba4b0202000101000001010200000101006fb21feead027da4873295affd6c4f3618fe176fa2fbf3e7b5ef1d9463b31e210112a6d0c44edc630d2724b1f57fea4f93308b1d22164402c65778bd99379c4733070000000000000020f2fd3c87b227f1015182fe4348ed680d7ed32bcd3269704252c03e1d0b13d30d6fb21feead027da4873295affd6c4f3618fe176fa2fbf3e7b5ef1d9463b31e2101000000000000000c0400000000000000", "hex"),
[
{
"header": "Transfer",
"prompt": "SUI"
},
{
"header": "From",
"prompt": "0x56b19e720f3bfa8caaef806afdd5dfaffd0d6ec9476323a14d1638ad734b2ba5",
"paginate": true
},
{
"header": "To",
"prompt": "0x4f2370b2a4810ad6c8e1cfd92cc8c8818fef8f59e3a80cea17871f78d850ba4b",
"paginate": true
},
{
"header": "Amount",
"prompt": "SUI 0.001"
},
{
"header": "Max Gas",
"prompt": "SUI 0.000001036"
},
{
"text": "Sign Transaction?",
"x": 19,
"y": 11
},
{
"text": "Confirm",
"x": 43,
"y": 11,
}
]
));
testTransaction(
"44'/4218'/0'",
Buffer.from("000000000002000840420f000000000000204f2370b2a4810ad6c8e1cfd92cc8c8818fef8f59e3a80cea17871f78d850ba4b0202000101000001010200000101006fb21feead027da4873295affd6c4f3618fe176fa2fbf3e7b5ef1d9463b31e210112a6d0c44edc630d2724b1f57fea4f93308b1d22164402c65778bd99379c4733070000000000000020f2fd3c87b227f1015182fe4348ed680d7ed32bcd3269704252c03e1d0b13d30d6fb21feead027da4873295affd6c4f3618fe176fa2fbf3e7b5ef1d9463b31e2101000000000000000c0400000000000000", "hex"),
[
{
"header": "Transfer",
"prompt": "SUI"
},
{
"header": "From",
"prompt": "0x56b19e720f3bfa8caaef806afdd5dfaffd0d6ec9476323a14d1638ad734b2ba5",
"paginate": true
},
{
"header": "To",
"prompt": "0x4f2370b2a4810ad6c8e1cfd92cc8c8818fef8f59e3a80cea17871f78d850ba4b",
"paginate": true
},
{
"header": "Amount",
"prompt": "SUI 0.001"
},
{
"header": "Max Gas",
"prompt": "SUI 0.000001036"
},
{
"text": "Sign Transaction?",
"x": 19,
"y": 11
},
{
"text": "Confirm",
"x": 43,
"y": 11,
}
]
));

it("can blind sign an unknown transaction", async function () {
const path = "44'/784'/0'";
const path = "44'/4218'/0'";
const txn = Buffer.from("00000000050205546e7f126d2f40331a543b9608439b582fd0d103000000000000002080fdabcc90498e7eb8413b140c4334871eeafa5a86203fd9cfdb032f604f49e1284af431cf032b5d85324135bf9a3073e920d7f5020000000000000020a06f410c175e828c24cee84cb3bd95cff25c33fbbdcb62c6596e8e423784ffe702d08074075c7097f361e8b443e2075a852a2292e8a08074075c7097f361e8b443e2075a852a2292e80180969800000000001643fb2578ff7191c643079a62c1cca8ec2752bc05546e7f126d2f40331a543b9608439b582fd0d103000000000000002080fdabcc90498e7eb8413b140c4334871eeafa5a86203fd9cfdb032f604f49e101000000000000002c01000000000000", "hex");
const prompts =
[
{
"header": "WARNING",
"prompt": "Transaction not recognized"
},
{
"header": "Transaction Hash",
"prompt": "0xfc2bce70e1cb980a6d49a32ff770a782ee13dabdecee085b82e0fdad5e92fcdd"
},
{
"text": "Blind Sign Transaction?",
"x": 4,
"y": 11
},
{
"text": "Confirm",
"x": 43,
"y": 11,
}
];
[
{
"header": "WARNING",
"prompt": "Transaction not recognized"
},
{
"header": "Transaction Hash",
"prompt": "0xfc2bce70e1cb980a6d49a32ff770a782ee13dabdecee085b82e0fdad5e92fcdd"
},
{
"text": "Blind Sign Transaction?",
"x": 4,
"y": 11
},
{
"text": "Confirm",
"x": 43,
"y": 11,
}
];

await toggleBlindSigningSettings();
await Axios.delete(BASE_URL + "/events");
Expand All @@ -110,33 +110,33 @@ describe("Signing tests", function() {
});

it("should reject signing a non-SUI coin transaction, if blind signing is not enabled", async function () {
const path = "44'/784'/0'";
const path = "44'/4218'/0'";
const txn = Buffer.from("AAAAAAADAQAe2uv1Mds+xCVK5Jv/Dv5cgEl/9DthDcpbjWcsmFpzbs6BNQAAAAAAIKPD8GQqgBpJZRV+nFDRE7rqR0Za8x0pyfLusVdpPPVRAAgADl+jHAAAAAAg5y3MHATlk+Ik5cPIdEz5iPANs1jcXZHVGjh4Mb16lwkCAgEAAAEBAQABAQIAAAECAF/sd27xyQe/W+gY4WRtPlQro1siWQu79s0pxbbCSRafAfnjaU5yJSFFDJznsAaBqbkiR9CB8DJqWki8fn8AUZeQz4E1AAAAAAAgTRU/MsawTJirpVwjDF8gyiEbaT0+7J0V8ifUEGGBkcVf7Hdu8ckHv1voGOFkbT5UK6NbIlkLu/bNKcW2wkkWn+gDAAAAAAAA8NdGAAAAAAAA", "base64");

await sendCommandExpectFail(async (client : Sui) => {
await sendCommandExpectFail(async (client: Sui) => {
await client.signTransaction(path, txn);
});
});

it("should reject signing an unknown transaction, if blind signing is not enabled", async function () {
const path = "44'/784'/0'";
const path = "44'/4218'/0'";
const txn = Buffer.from("00000000050205546e7f126d2f40331a543b9608439b582fd0d103000000000000002080fdabcc90498e7eb8413b140c4334871eeafa5a86203fd9cfdb032f604f49e1284af431cf032b5d85324135bf9a3073e920d7f5020000000000000020a06f410c175e828c24cee84cb3bd95cff25c33fbbdcb62c6596e8e423784ffe702d08074075c7097f361e8b443e2075a852a2292e8a08074075c7097f361e8b443e2075a852a2292e80180969800000000001643fb2578ff7191c643079a62c1cca8ec2752bc05546e7f126d2f40331a543b9608439b582fd0d103000000000000002080fdabcc90498e7eb8413b140c4334871eeafa5a86203fd9cfdb032f604f49e101000000000000002c01000000000000", "hex");

await sendCommandExpectFail(async (client : Sui) => {
await sendCommandExpectFail(async (client: Sui) => {
await client.signTransaction(path, txn);
});
});

it("Rejects a blind sign with mismatching lengths", async function () {
const path = "44'/784'/0'";
const path = "44'/4218'/0'";
const txn = Buffer.from("00000000050205546e7f126d2f40331a543b9608439b582fd0d103000000000000002080fdabcc90498e7eb8413b140c4334871eeafa5a86203fd9cfdb032f604f49e1284af431cf032b5d85324135bf9a3073e920d7f5020000000000000020a06f410c175e828c24cee84cb3bd95cff25c33fbbdcb62c6596e8e423784ffe702d08074075c7097f361e8b443e2075a852a2292e8a08074075c7097f361e8b443e2075a852a2292e80180969800000000001643fb2578ff7191c643079a62c1cca8ec2752bc05546e7f126d2f40331a543b9608439b582fd0d103000000000000002080fdabcc90498e7eb8413b140c4334871eeafa5a86203fd9cfdb032f604f49e101000000000000002c01000000000000", "hex");

await toggleBlindSigningSettings();
await Axios.delete(BASE_URL + "/events");
await sendCommandExpectFail(async (client : any) => {
await sendCommandExpectFail(async (client: any) => {
client.oldSendChunks = client.sendChunks;
client.sendChunks = (cla, ins, p1, p2, payload) => {
payload[0][3]=payload[0][3]+20; // Add 20*2^24 to the transaction length, so we'll run out of input.
payload[0][3] = payload[0][3] + 20; // Add 20*2^24 to the transaction length, so we'll run out of input.
const rv = client.oldSendChunks(cla, ins, p1, p2, payload);
return rv;
}
Expand All @@ -146,7 +146,7 @@ describe("Signing tests", function() {
await sendCommandAndAccept(
async client => {
const { publicKey } = await client.getPublicKey(path);
expect(publicKey.length>0).to.equal(true);
expect(publicKey.length > 0).to.equal(true);
},
[]);
await Axios.delete(BASE_URL + "/events");
Expand Down
Loading