Skip to content
This repository has been archived by the owner on Jan 13, 2025. It is now read-only.

Commit

Permalink
fix: add Token::setOwner
Browse files Browse the repository at this point in the history
  • Loading branch information
mvines committed Oct 21, 2018
1 parent 8d0dbf4 commit 315ee96
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 11 deletions.
9 changes: 7 additions & 2 deletions module.flow.js
Original file line number Diff line number Diff line change
Expand Up @@ -145,15 +145,20 @@ declare module '@solana/web3.js' {
): Promise<void>;
approve(
owner: Account,
source: PublicKey,
account: PublicKey,
delegate: PublicKey,
amount: number | TokenAmount
): Promise<void>;
revoke(
owner: Account,
source: PublicKey,
account: PublicKey,
delegate: PublicKey
): Promise<void>;
setOwner(
owner: Account,
account: PublicKey,
newOwner: PublicKey
): Promise<void>;
}

// === src/loader.js ===
Expand Down
47 changes: 41 additions & 6 deletions src/token-program.js
Original file line number Diff line number Diff line change
Expand Up @@ -402,13 +402,13 @@ export class Token {
* Grant a third-party permission to transfer up the specified number of tokens from an account
*
* @param owner Owner of the source token account
* @param source Source token account
* @param account Public key of the token account
* @param delegate Token account authorized to perform a transfer tokens from the source account
* @param amount Maximum number of tokens the delegate may transfer
*/
async approve(
owner: Account,
source: PublicKey,
account: PublicKey,
delegate: PublicKey,
amount: number | TokenAmount
): Promise<void> {
Expand All @@ -429,7 +429,7 @@ export class Token {

const transaction = new Transaction({
fee: 0,
keys: [owner.publicKey, source, delegate],
keys: [owner.publicKey, account, delegate],
programId: this.programId,
userdata,
});
Expand All @@ -440,15 +440,50 @@ export class Token {
* Remove approval for the transfer of any remaining tokens
*
* @param owner Owner of the source token account
* @param source Source token account
* @param account Public key of the token account
* @param delegate Token account to revoke authorization from
*/
revoke(
owner: Account,
source: PublicKey,
account: PublicKey,
delegate: PublicKey
): Promise<void> {
return this.approve(owner, source, delegate, 0);
return this.approve(owner, account, delegate, 0);
}

/**
* Assign a new owner to the account
*
* @param owner Owner of the token account
* @param account Public key of the token account
* @param newOwner New owner of the token account
*/
async setOwner(
owner: Account,
account: PublicKey,
newOwner: PublicKey,
): Promise<void> {

const userdataLayout = BufferLayout.struct([
BufferLayout.u32('instruction'),
]);

const userdata = Buffer.alloc(userdataLayout.span);
userdataLayout.encode(
{
instruction: 4, // SetOwner instruction
},
userdata,
);

const keys = [owner.publicKey, account,newOwner];
const transaction = new Transaction({
fee: 0,
keys,
programId: this.programId,
userdata,
});
await sendAndConfirmTransaction(this.connection, owner, transaction);
}
}

Expand Down
31 changes: 28 additions & 3 deletions test/token-program.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -473,7 +473,7 @@ test('invalid approve', async () => {
const account2 = await testToken.newAccount(owner);

// account2 is not a delegate account of account1
expect(
await expect(
testToken.approve(
owner,
account1,
Expand All @@ -483,7 +483,7 @@ test('invalid approve', async () => {
).rejects.toThrow();

// account1Delegate is not a delegate account of account2
expect(
await expect(
testToken.approve(
owner,
account2,
Expand Down Expand Up @@ -548,7 +548,7 @@ test.skip('fail on approve overspend', async () => {
expect(delegateAccountInfo.amount.toNumber()).toBe(0);
expect(delegateAccountInfo.originalAmount.toNumber()).toBe(2);

expect(
await expect(
testToken.transfer(
owner,
account1Delegate,
Expand All @@ -557,3 +557,28 @@ test.skip('fail on approve overspend', async () => {
)
).rejects.toThrow();
});


test('set owner', async () => {
if (mockRpcEnabled) {
console.log('non-live test skipped');
return;
}

const connection = new Connection(url);
const owner = await newAccountWithTokens(connection);
const newOwner = await newAccountWithTokens(connection);

const account = await testToken.newAccount(owner);

await testToken.setOwner(owner, account, newOwner.publicKey);
await expect(
testToken.setOwner(owner, account, newOwner.publicKey)
).rejects.toThrow();

await testToken.setOwner(newOwner, account, owner.publicKey);
await expect(
testToken.setOwner(newOwner, account, owner.publicKey)
).rejects.toThrow();

});

0 comments on commit 315ee96

Please sign in to comment.