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: Add signInMulti method #811

Open
wants to merge 35 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
264f904
Added interfaces for signInMulti in wallet types.
kujtimprenkuSQA May 19, 2023
627d59b
Add signInMulti method to each wallet.
kujtimprenkuSQA May 19, 2023
142ecb3
Merge branch 'dev' into SQC-540/add-signin-multi
kujtimprenkuSQA May 19, 2023
d40159a
Fix jsdoc warnings and improved docs.
kujtimprenkuSQA May 19, 2023
35448f4
Added logic to allow sign-in with multiple contracts.
kujtimprenkuSQA May 22, 2023
60ac5a0
Fix build for here wallet.
kujtimprenkuSQA May 22, 2023
6e3d5f3
Added contracts to ModalOptions interface.
kujtimprenkuSQA May 23, 2023
512f12b
Added logic to handle signInMulti in modal-ui and modal-ui-js.
kujtimprenkuSQA May 23, 2023
fb519ea
Added docs for .
kujtimprenkuSQA May 23, 2023
5f6bfd4
Fix docs since permissions is required for signInMulti.
kujtimprenkuSQA May 23, 2023
da54351
Remove contracts from setupModal in angular example.
kujtimprenkuSQA May 23, 2023
72b83e5
Export MultiContractState interface.
kujtimprenkuSQA May 23, 2023
8121e5e
Removed signInMulti from inside the modules instead throw when decora…
kujtimprenkuSQA Jun 27, 2023
f910c39
Merge branch 'dev' into SQC-540/add-signin-multi
kujtimprenkuSQA Jun 27, 2023
8d0d967
Removed contractId and added made contracts required, signAndSendTran…
amirsaran3 Jul 3, 2023
2f559f7
Added method to update old contract state for signed in users
amirsaran3 Jul 5, 2023
1188905
Merge branch 'dev' into SQC-540/add-signin-multi
kujtimprenkuSQA Jul 20, 2023
668d7a4
Trigger signInMulti for ledger when there are multiple contracts.
kujtimprenkuSQA Jul 21, 2023
47bedc6
Merge branch 'dev' into SQC-540/add-signin-multi
kujtimprenkuSQA Jul 24, 2023
970b9d1
Merge branch 'SQC-540/add-signin-multi' into SQC-540/add-signin-multi…
kujtimprenkuSQA Jul 24, 2023
9c487aa
Merge branch 'SQC-540/add-signin-multi' of https://github.com/near/wa…
kujtimprenkuSQA Sep 18, 2023
8433139
Merge branch 'dev' into SQC-540/add-signin-multi
kujtimprenkuSQA Sep 18, 2023
9448d81
Merge branch 'SQC-540/add-signin-multi' into SQC-540/add-signin-multi…
kujtimprenkuSQA Sep 18, 2023
45da765
Merge branch 'dev' into SQC-540/add-signin-multi
kujtimprenkuSQA Feb 6, 2024
6c1e65c
Merge branch 'SQC-540/add-signin-multi' into SQC-540/add-signin-multi…
kujtimprenkuSQA Feb 6, 2024
f7bd15e
fix near-mobile-wallet, near-snap and ramper-wallet methods
gtsonevv Jul 24, 2024
1ff90b8
fix if check
gtsonevv Jul 24, 2024
142c447
update receiverId value
gtsonevv Jul 25, 2024
565665d
Merge pull request #1138 from near/SQC-540/add-signin-multi-breaking-…
gtsonevv Jul 25, 2024
f39d4b3
Update signedIn emit data; Fix resolveStorageState logic
gtsonevv Jul 29, 2024
7cf58bb
Update docs
gtsonevv Jul 30, 2024
ff6d042
Merge pull request #847 from near/SQC-540/add-signin-multi-breaking-c…
gtsonevv Aug 2, 2024
422d9fb
Merge branch 'dev' into SQC-540/add-signin-multi
gtsonevv Aug 2, 2024
aa0db8a
Fix merge issues
gtsonevv Aug 2, 2024
180f5b8
Fix modal errors
gtsonevv Aug 2, 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
Original file line number Diff line number Diff line change
Expand Up @@ -291,14 +291,14 @@ export class ContentComponent implements OnInit, OnDestroy {
}

async addMessages(message: string, donation: string, multiple: boolean) {
const { contract } = this.selector.store.getState();
const wallet = await this.selector.wallet();

if (!multiple) {
return wallet
.signAndSendTransaction({
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
signerId: this.accountId!,
receiverId: CONTRACT_ID,
actions: [
{
type: "FunctionCall",
Expand Down Expand Up @@ -327,7 +327,7 @@ export class ContentComponent implements OnInit, OnDestroy {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
signerId: this.accountId!,
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
receiverId: contract!.contractId,
receiverId: CONTRACT_ID,
actions: [
{
type: "FunctionCall",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ export class WalletSelectorComponent implements OnInit {
});

const _modal = setupModal(_selector, {
contractId: CONTRACT_ID,
contracts: [{ receiverId: CONTRACT_ID, methodNames: [] }],
});
const state = _selector.store.getState();

Expand Down
4 changes: 2 additions & 2 deletions examples/react/components/Content.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -160,12 +160,12 @@ const Content: React.FC = () => {

const addMessages = useCallback(
async (message: string, donation: string, multiple: boolean) => {
const { contract } = selector.store.getState();
const wallet = await selector.wallet();
if (!multiple) {
return wallet
.signAndSendTransaction({
signerId: accountId!,
receiverId: CONTRACT_ID,
actions: [
{
type: "FunctionCall",
Expand All @@ -191,7 +191,7 @@ const Content: React.FC = () => {
for (let i = 0; i < 2; i += 1) {
transactions.push({
signerId: accountId!,
receiverId: contract!.contractId,
receiverId: CONTRACT_ID,
actions: [
{
type: "FunctionCall",
Expand Down
2 changes: 1 addition & 1 deletion examples/react/contexts/WalletSelectorContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ export const WalletSelectorContextProvider: React.FC<{
],
});
const _modal = setupModal(_selector, {
contractId: CONTRACT_ID,
contracts: [{ receiverId: CONTRACT_ID, methodNames: [] }],
});
const state = _selector.store.getState();
setAccounts(state.accounts);
Expand Down
6 changes: 3 additions & 3 deletions packages/bitget-wallet/src/lib/bitget-wallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -191,15 +191,15 @@ const BitgetWallet: WalletBehaviourFactory<InjectedWallet> = async ({
async signAndSendTransaction({ signerId, receiverId, actions }) {
logger.log("signAndSendTransaction", { signerId, receiverId, actions });

const { contract } = store.getState();
const { contracts } = store.getState();

if (!_state.wallet.isSignedIn() || !contract) {
if (!_state.wallet.isSignedIn() || contracts.length < 1) {
throw new Error("Wallet not signed in");
}

return _state.wallet
.signAndSendTransaction({
receiverId: receiverId || contract.contractId,
receiverId: receiverId,
actions: actions,
})
.then((res) => {
Expand Down
8 changes: 4 additions & 4 deletions packages/coin98-wallet/src/lib/coin98-wallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,11 @@ const Coin98Wallet: WalletBehaviourFactory<InjectedWallet> = async ({
};

const transformTransactions = (
transactions: Array<Optional<Transaction, "signerId" | "receiverId">>
transactions: Array<Optional<Transaction, "signerId">>
): Array<Transaction> => {
const { contract } = store.getState();
const { contracts } = store.getState();

if (!contract) {
if (contracts.length < 1) {
throw new Error("Wallet not signed in");
}

Expand All @@ -87,7 +87,7 @@ const Coin98Wallet: WalletBehaviourFactory<InjectedWallet> = async ({
return transactions.map((transaction) => {
return {
signerId: transaction.signerId || account.accountId,
receiverId: transaction.receiverId || contract.contractId,
receiverId: transaction.receiverId,
actions: transaction.actions,
};
});
Expand Down
12 changes: 6 additions & 6 deletions packages/core/docs/api/state.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
## API Reference (State)

### `.contract`
### `.contracts`

**Returns**

- `ContractState | null`
- `MultiContractState`
- `contractId` (`string`): Account ID of the Smart Contract.
- `methodNames` (`Array<string>`): List of methods that can only be invoked on the Smart Contract. Empty list means no restriction.

**Description**

Returns the signed in contract.
Returns the signed in contracts when signing-in with `signInMulti`.

**Example**

```ts
const { contract } = selector.store.getState();
console.log(contract); // { contractId: "test.testnet", methodNames: [] }
// MultiContractState = Array<ContractState>;
const { contracts } = selector.store.getState();
console.log(contracts); // [{ contractId: "test.testnet", methodNames: [] }, { contractId: "test1.testnet", methodNames: [] }]
```

### `.modules`
Expand Down
96 changes: 92 additions & 4 deletions packages/core/docs/api/wallet.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,9 @@ Returns meta information about the wallet such as `name`, `description`, `iconUr
- `contractId` (`string`): Account ID of the Smart Contract.
- `methodNames` (`Array<string>?`): Specify limited access to particular methods on the Smart Contract.
- `accounts` (`Array<{derivationPath: string, publicKey: string, accountId: string}>?`): Required for hardware wallets (e.g. Ledger). This is a list of `accounts` linked to public keys on your device.
- `qrCodeModal` (`boolean?`): Optional for bridge wallets (e.g Wallet Connect). This indicates whether to render QR Code in wallet selector modal or use the default vendor modal.
- `successUrl` (`string?`): Optional for browser wallets (e.g MyNearWallet and HERE Wallet). After successfully signing in where to redirect.
- `failureUrl` (`string?`): Optional for browser wallets (e.g MyNearWallet and HERE Wallet). After failing to sign in where to redirect.
- `qrCodeModal` (`boolean?`): Optional for bridge wallets (e.g. Wallet Connect). This indicates whether to render QR Code in wallet selector modal or use the default vendor modal.
- `successUrl` (`string?`): Optional for browser wallets (e.g. MyNearWallet and NEAR Wallet). After successfully signing in where to redirect.
- `failureUrl` (`string?`): Optional for browser wallets (e.g. MyNearWallet and NEAR Wallet). After failing to sign in where to redirect.

**Returns**

Expand Down Expand Up @@ -148,6 +148,94 @@ Programmatically sign in. Hardware wallets (e.g. Ledger) require `derivationPath
})();
```

### `.signInMulti(params)`

**Parameters**

- `params` (`object`)

- `permissions`(`Array<{allowance?: BN, receiverId: string, methodNames: Array<string>}>`): List of Account ID-s of the Smart Contracts and the limited access to particular methods on the Smart Contract.
- `accounts` (`Array<{derivationPath: string, publicKey: string, accountId: string}>?`): Required for hardware wallets (e.g. Ledger). This is a list of `accounts` linked to public keys on your device.
- `qrCodeModal` (`boolean?`): Optional for bridge wallets (e.g. Wallet Connect). This indicates whether to render QR Code in wallet selector modal or use the default vendor modal.
- `successUrl` (`string?`): Optional for browser wallets (e.g. MyNearWallet and NEAR Wallet). After successfully signing in where to redirect.
- `failureUrl` (`string?`): Optional for browser wallets (e.g. MyNearWallet and NEAR Wallet). After failing to sign in where to redirect.

**Returns**

- `Promise<Array<Account>>`

**Description**

Programmatically sign in. Hardware wallets (e.g. Ledger) require `derivationPaths` to validate access key permissions.

**Example**

```ts
// NEAR Wallet.
(async () => {
const wallet = await selector.wallet("near-wallet");
const accounts = await wallet.signInMulti({
permissions: [
{ receiverId: "test.testnet", methodNames: [] },
{ receiverId: "test1.testnet", methodNames: [] }
]
});
})();

// Sender.
(async () => {
const wallet = await selector.wallet("sender");
const accounts = await wallet.signInMulti({
permissions: [
{ receiverId: "test.testnet", methodNames: [] },
{ receiverId: "test1.testnet", methodNames: [] }
]
});
})();

// Math Wallet.
(async () => {
const wallet = await selector.wallet("math-wallet");
const accounts = await wallet.signInMulti({
permissions: [
{ receiverId: "test.testnet", methodNames: [] },
{ receiverId: "test1.testnet", methodNames: [] }
]
});
})();

// Ledger
(async () => {
const wallet = await selector.wallet("ledger");
const derivationPath = "44'/397'/0'/0'/1'";
const publicKey = await wallet.getPublicKey(derivationPath);
const accountId = "youraccountid.testnet"

const accounts = await wallet.signIn({
permissions: [
{ receiverId: "test.testnet", methodNames: [] },
{ receiverId: "test1.testnet", methodNames: [] }
],
accounts: [{
derivationPath,
publicKey,
accountId
}],
});
})();

// WalletConnect.
(async () => {
const wallet = await selector.wallet("wallet-connect");
const accounts = await wallet.signInMulti({
permissions: [
{ receiverId: "test.testnet", methodNames: [] },
{ receiverId: "test1.testnet", methodNames: [] }
]
});
})();
```

### `.signOut()`

**Parameters**
Expand Down Expand Up @@ -230,7 +318,7 @@ Signs the message and verifies the owner. Message is not sent to blockchain.

- `params` (`object`)
- `signerId` (`string?`): Account ID used to sign the transaction. Defaults to the first account.
- `receiverId` (`string?`): Account ID to receive the transaction. Defaults to `contractId` defined in `.init`.
- `receiverId` (`string`): Account ID to receive the transaction. Defaults to `contractId` defined in `.init`.
- `actions` (`Array<Action>`): NEAR Action(s) to sign and send to the network (e.g. `FunctionCall`). You can find more information on `Action` [here](./transactions.md).
- `callbackUrl` (`string?`): Applicable to browser wallets (e.g. MyNearWallet). This the callback url once the transaction is approved.

Expand Down
6 changes: 6 additions & 0 deletions packages/core/docs/guides/custom-wallets.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@ const MyWallet: WalletBehaviourFactory<BrowserWallet> = ({
return [];
},

async signInMulti({ permissions }) {
// Sign in to My Wallet with multiple contracts.

return [];
},

async signOut() {
// Sign out from accounts and cleanup (e.g. listeners).
},
Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export type { Optional } from "./lib/utils.types";
export type {
WalletSelectorState,
ContractState,
MultiContractState,
ModuleState,
AccountState,
} from "./lib/store.types";
Expand All @@ -35,6 +36,7 @@ export type {
WalletMetadata,
WalletEvents,
SignInParams,
SignInMultiParams,
BrowserWalletMetadata,
BrowserWalletBehaviour,
BrowserWallet,
Expand Down
3 changes: 3 additions & 0 deletions packages/core/src/lib/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,8 @@ export const REMEMBER_RECENT_WALLETS_STATE = {
export const CONTRACT = "contract";
export const PENDING_CONTRACT = "contract:pending";

export const CONTRACTS = "contracts";
export const PENDING_CONTRACTS = "contracts:pending";

export const SELECTED_WALLET_ID = `selectedWalletId`;
export const PENDING_SELECTED_WALLET_ID = `selectedWalletId:pending`;
Loading
Loading