-
Notifications
You must be signed in to change notification settings - Fork 44
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add support for federated keyless (#495)
* Add support for federated keyless * update * federated local * add example * undup code * fmt * update examples * update tests * revert endpoints * update util * add todo * update jwk update * address comments * update * update * update ternary * fix async proof submission * fixes * fmt * update changelog * fix examples * fund account * fix test
- Loading branch information
1 parent
c75501c
commit b20adf5
Showing
23 changed files
with
1,144 additions
and
377 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
/* eslint-disable max-len */ | ||
/* eslint-disable no-console */ | ||
|
||
/** | ||
* This example shows how to use the Federated Keyless accounts on Aptos | ||
*/ | ||
|
||
import { Account, AccountAddress, Aptos, AptosConfig, EphemeralKeyPair, Network } from "@aptos-labs/ts-sdk"; | ||
import * as readlineSync from "readline-sync"; | ||
|
||
const ALICE_INITIAL_BALANCE = 100_000_000; | ||
const BOB_INITIAL_BALANCE = 100_000_000; | ||
const TRANSFER_AMOUNT = 10_000; | ||
|
||
/** | ||
* Prints the balance of an account | ||
* @param aptos | ||
* @param name | ||
* @param address | ||
* @returns {Promise<*>} | ||
* | ||
*/ | ||
const balance = async (aptos: Aptos, name: string, address: AccountAddress) => { | ||
const amount = await aptos.getAccountAPTAmount({ | ||
accountAddress: address, | ||
}); | ||
console.log(`${name}'s balance is: ${amount}`); | ||
return amount; | ||
}; | ||
|
||
const example = async () => { | ||
// Setup the client | ||
const config = new AptosConfig({ network: Network.DEVNET }); | ||
const aptos = new Aptos(config); | ||
|
||
// Generate the ephemeral (temporary) key pair that will be used to sign transactions. | ||
const ephemeralKeyPair = EphemeralKeyPair.generate(); | ||
|
||
console.log("\n=== Federated Keyless Account Example ===\n"); | ||
|
||
const link = `https://dev-qtdgjv22jh0v1k7g.us.auth0.com/authorize?client_id=dzqI77x0M5YwdOSUx6j25xkdOt8SIxeE&redirect_uri=http%3A%2F%2Flocalhost%3A5173%2Fcallback&response_type=id_token&scope=openid&nonce=${ephemeralKeyPair.nonce}`; | ||
console.log(`${link}\n`); | ||
|
||
console.log("1. Open the link above"); | ||
console.log("2. Log in with your Google account"); | ||
console.log("3. Click 'Exchange authorization code for tokens"); | ||
console.log("4. Copy the 'id_token' - (toggling 'Wrap lines' option at the bottom makes this easier)\n"); | ||
|
||
function inputJwt(): string { | ||
const jwt: string = readlineSync.question("Paste the JWT (id_token) token here and press enter:\n\n", { | ||
hideEchoBack: false, | ||
}); | ||
return jwt; | ||
} | ||
|
||
const jwt = inputJwt(); | ||
|
||
const bob = Account.generate(); | ||
|
||
// Derive the Keyless Account from the JWT and ephemeral key pair. | ||
const alice = await aptos.deriveKeylessAccount({ | ||
jwt, | ||
ephemeralKeyPair, | ||
jwkAddress: bob.accountAddress, | ||
}); | ||
|
||
console.log("\n=== Addresses ===\n"); | ||
console.log(`Alice's keyless account address is: ${alice.accountAddress}`); | ||
console.log(`Alice's nonce is: ${ephemeralKeyPair.nonce}`); | ||
console.log(`Alice's ephem pubkey is: ${ephemeralKeyPair.getPublicKey().toString()}`); | ||
console.log(`\nBob's account address is: ${bob.accountAddress}`); | ||
|
||
// Fund the accounts | ||
console.log("\n=== Funding accounts ===\n"); | ||
|
||
await aptos.fundAccount({ | ||
accountAddress: alice.accountAddress, | ||
amount: ALICE_INITIAL_BALANCE, | ||
options: { waitForIndexer: false }, | ||
}); | ||
await aptos.fundAccount({ | ||
accountAddress: bob.accountAddress, | ||
amount: BOB_INITIAL_BALANCE, | ||
options: { waitForIndexer: false }, | ||
}); | ||
|
||
// // Show the balances | ||
console.log("\n=== Balances ===\n"); | ||
const aliceBalance = await balance(aptos, "Alice", alice.accountAddress); | ||
const bobBalance = await balance(aptos, "Bob", bob.accountAddress); | ||
|
||
const iss = "https://dev-qtdgjv22jh0v1k7g.us.auth0.com/"; | ||
|
||
console.log("\n=== Installing JWKs ===\n"); | ||
const jwkTxn = await aptos.updateFederatedKeylessJwkSetTransaction({ sender: bob, iss }); | ||
const committedJwkTxn = await aptos.signAndSubmitTransaction({ signer: bob, transaction: jwkTxn }); | ||
await aptos.waitForTransaction({ transactionHash: committedJwkTxn.hash }); | ||
console.log(`Committed transaction: ${committedJwkTxn.hash}`); | ||
|
||
// Transfer between users | ||
const transaction = await aptos.transferCoinTransaction({ | ||
sender: alice.accountAddress, | ||
recipient: bob.accountAddress, | ||
amount: TRANSFER_AMOUNT, | ||
}); | ||
|
||
console.log("\n=== Transferring ===\n"); | ||
const committedTxn = await aptos.signAndSubmitTransaction({ signer: alice, transaction }); | ||
|
||
await aptos.waitForTransaction({ transactionHash: committedTxn.hash }); | ||
console.log(`Committed transaction: ${committedTxn.hash}`); | ||
|
||
console.log("\n=== Balances after transfer ===\n"); | ||
const newAliceBalance = await balance(aptos, "Alice", alice.accountAddress); | ||
const newBobBalance = await balance(aptos, "Bob", bob.accountAddress); | ||
|
||
// Bob should have the transfer amount minus gas to insert jwk | ||
if (TRANSFER_AMOUNT <= newBobBalance - bobBalance) throw new Error("Bob's balance after transfer is incorrect"); | ||
|
||
// Alice should have the remainder minus gas | ||
if (TRANSFER_AMOUNT >= aliceBalance - newAliceBalance) throw new Error("Alice's balance after transfer is incorrect"); | ||
}; | ||
|
||
example(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
/* eslint-disable max-len */ | ||
/* eslint-disable no-console */ | ||
|
||
/** | ||
* This example shows how to use install JWKs on an account to support Federated Keyless Accounts | ||
*/ | ||
|
||
import { Aptos, AptosConfig, EphemeralKeyPair, Network } from "@aptos-labs/ts-sdk"; | ||
import * as readlineSync from "readline-sync"; | ||
|
||
const example = async () => { | ||
const config = new AptosConfig({ network: Network.DEVNET }); | ||
const aptos = new Aptos(config); | ||
|
||
// Generate the ephemeral (temporary) key pair that will be used to sign transactions. | ||
const ephemeralKeyPair = EphemeralKeyPair.generate(); | ||
|
||
console.log("\n=== Federated Keyless JWK Installation ===\n"); | ||
|
||
const link = `https://accounts.google.com/o/oauth2/v2/auth/oauthchooseaccount?redirect_uri=https%3A%2F%2Fdevelopers.google.com%2Foauthplayground&prompt=consent&response_type=code&client_id=407408718192.apps.googleusercontent.com&scope=openid&access_type=offline&service=lso&o2v=2&theme=glif&flowName=GeneralOAuthFlow&nonce=${ephemeralKeyPair.nonce}`; | ||
console.log(`${link}\n`); | ||
|
||
console.log("1. Open the link above"); | ||
console.log("2. Log in with your Google account"); | ||
console.log("3. Click 'Exchange authorization code for tokens"); | ||
console.log("4. Copy the 'id_token' - (toggling 'Wrap lines' option at the bottom makes this easier)\n"); | ||
|
||
function inputJwt(): string { | ||
const jwt: string = readlineSync.question("Paste the JWT (id_token) token here and press enter:\n\n", { | ||
hideEchoBack: false, | ||
}); | ||
return jwt; | ||
} | ||
|
||
function inputIss(): string { | ||
const jwt: string = readlineSync.question( | ||
"\nInput the iss claim of your federated OIDC provider and press enter (e.g. https://dev-qtdgjv22jh0v1k7g.us.auth0.com/):\n\n", | ||
{ | ||
hideEchoBack: false, | ||
}, | ||
); | ||
return jwt; | ||
} | ||
|
||
const jwt = inputJwt(); | ||
const iss = inputIss(); | ||
|
||
const alice = await aptos.deriveKeylessAccount({ | ||
jwt, | ||
ephemeralKeyPair, | ||
}); | ||
await aptos.fundAccount({ | ||
accountAddress: alice.accountAddress, | ||
amount: 100_000_000, | ||
}); | ||
|
||
const jwkTxn = await aptos.updateFederatedKeylessJwkSetTransaction({ sender: alice, iss }); | ||
await aptos.signAndSubmitTransaction({ signer: alice, transaction: jwkTxn }); | ||
|
||
console.log("\n=== Addresses ===\n"); | ||
console.log(`JWKs were installed at - ${alice.accountAddress}\n`); | ||
console.log("Use it to construct Federated Keyless Accounts for your federated JWT tokens\n\n"); | ||
console.log( | ||
`await aptos.deriveKeylessAccount({\n jwt,\n ephemeralKeyPair,\n jwkAddress: "${alice.accountAddress}",\n});`, | ||
); | ||
}; | ||
|
||
example(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
[package] | ||
name = "update_jwk" | ||
version = "1.0.0" | ||
authors = [] | ||
|
||
[addresses] | ||
|
||
[dev-addresses] | ||
|
||
[dependencies.AptosFramework] | ||
git = "https://github.com/aptos-labs/aptos-core.git" | ||
rev = "devnet" | ||
subdir = "aptos-move/framework/aptos-framework" | ||
|
||
[dev-dependencies] |
Binary file not shown.
25 changes: 25 additions & 0 deletions
25
examples/typescript/move/update_jwk/scripts/update_jwk.move
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
script { | ||
use aptos_framework::jwks; | ||
use std::string::String; | ||
use std::vector; | ||
fun main(account: &signer, iss: vector<u8>, kid_vec: vector<String>, alg_vec: vector<String>, e_vec: vector<String>, n_vec: vector<String>) { | ||
assert!(!vector::is_empty(&kid_vec), 0); | ||
let num_jwk = vector::length<String>(&kid_vec); | ||
assert!(vector::length(&alg_vec) == num_jwk , 0); | ||
assert!(vector::length(&e_vec) == num_jwk, 0); | ||
assert!(vector::length(&n_vec) == num_jwk, 0); | ||
|
||
let remove_all_patch = jwks::new_patch_remove_all(); | ||
let patches = vector[remove_all_patch]; | ||
while (!vector::is_empty(&kid_vec)) { | ||
let kid = vector::pop_back(&mut kid_vec); | ||
let alg = vector::pop_back(&mut alg_vec); | ||
let e = vector::pop_back(&mut e_vec); | ||
let n = vector::pop_back(&mut n_vec); | ||
let jwk = jwks::new_rsa_jwk(kid, alg, e, n); | ||
let patch = jwks::new_patch_upsert_jwk(iss, jwk); | ||
vector::push_back(&mut patches, patch) | ||
}; | ||
jwks::patch_federated_jwks(account, patches); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.